Removing atmosphere, revert to plain websockets
diff --git a/wave/build.gradle b/wave/build.gradle
index f67a9fa..232a286 100644
--- a/wave/build.gradle
+++ b/wave/build.gradle
@@ -124,10 +124,26 @@
             [group: "commons-httpclient", name: "commons-httpclient", version: "3.1"],                          // [?, ?]
             [group: "commons-lang", name: "commons-lang", version: "2.5"],                                      // [?, ?]
             [group: "commons-fileupload", name: "commons-fileupload", version: "1.3.2"],                        // [11/2016, 6/2017]
+            [group: "commons-logging", name: "commons-logging-api", version: "1.1"],                            // [?, ?]
+            [group: "commons-logging", name: "commons-logging", version: "1.1.1"],                              // [?, ?]
+            [group: "com.google.code.findbugs", name: "jsr305", version: "2.0.1"],                              // [?, ?]
+            [group: "com.google.code.gson", name: "gson", version: "2.2.4"],                                    // [?, ?]
+            [group: "com.google.guava", name: "guava", version: "20.0"],                                        // [?, ?]
+            [group: "com.google.guava", name: "guava-gwt", version: "20.0"],                                    // [?, ?]
+            [group: "com.google.gxp", name: "google-gxp", version: "0.2.4-beta"],                               // [?, ?]
+            [group: "com.google.inject.extensions", name: "guice-assistedinject", version: "3.0"],              // [?, ?]
+            [group: "com.google.inject.extensions", name: "guice-servlet", version: "3.0"],                     // [?, ?]
+            [group: "com.google.inject", name: "guice", version: "3.0"],                                        // [?, ?]
+            [group: "com.google.protobuf", name: "protobuf-java", version: "2.6.1"],                            // [?, ?]
+            [group: "com.google.inject", name: "guice", version:"4.1.0"],					// [?, ?]
+            [group: "com.google.inject.extensions", name: "guice-servlet", version:"4.1.0"],			// [?, ?]
+            [group: "com.googlecode.protobuf-java-format", name: "protobuf-java-format", version: "1.2"],       // [?, ?]
+            [group: "com.typesafe", name: "config", version: "1.2.1"],                                          // [?, ?]
+            [group: "dom4j", name: "dom4j", version: "1.6.1"],                                                  // [?, ?]
+            [group: "eu.infomas", name: "annotation-detector", version: "3.0.0"],                               // [?, ?]
+            [group: "org.antlr", name: "antlr", version: "3.2"],                                                // [?, ?]
             [group: "org.apache.velocity", name: "velocity", version: "1.6.3"],                                 // [?, ?]
             [group: "org.apache.lucene", name: "lucene-core", version: "3.5.0"],                                // [?, ?]
-            [group: "org.atmosphere", name: "atmosphere-guice", version: "0.8.3"],                              // [?, ?]
-            [group: "org.atmosphere", name: "atmosphere-runtime", version: "2.1.0"],                            // [?, ?]
             [group: "org.bouncycastle", name: "bcprov-jdk16", version: "1.45"],                                 // [?, ?]
             [group: "org.eclipse.jetty", name: "jetty-annotations", version: "9.2.14.v20151106"],               // [?, ?]
             [group: "org.eclipse.jetty", name: "jetty-client", version: "9.2.14.v20151106"],                    // [?, ?]
diff --git a/wave/dependencies/compile/runtime/javascript-2.1.5.war b/wave/dependencies/compile/runtime/javascript-2.1.5.war
deleted file mode 100644
index d6a099f..0000000
--- a/wave/dependencies/compile/runtime/javascript-2.1.5.war
+++ /dev/null
Binary files differ
diff --git a/wave/dependencies/compile/runtime/javascript-2.1.5/javascript/atmosphere-min.js b/wave/dependencies/compile/runtime/javascript-2.1.5/javascript/atmosphere-min.js
deleted file mode 100644
index 641d6c4..0000000
--- a/wave/dependencies/compile/runtime/javascript-2.1.5/javascript/atmosphere-min.js
+++ /dev/null
@@ -1,1028 +0,0 @@
-(function(a,b){if(typeof define==="function"&&define.amd){define(b)
-}else{a.atmosphere=b()
-}}(this,function(){var c="2.1.5-javascript",a={},d,g=[],f=[],e=0,b=Object.prototype.hasOwnProperty;
-a={onError:function(h){},onClose:function(h){},onOpen:function(h){},onReopen:function(h){},onMessage:function(h){},onReconnect:function(i,h){},onMessagePublished:function(h){},onTransportFailure:function(i,h){},onLocalMessage:function(h){},onFailureToReconnect:function(i,h){},onClientTimeout:function(h){},AtmosphereRequest:function(M){var O={timeout:300000,method:"GET",headers:{},contentType:"",callback:null,url:"",data:"",suspend:true,maxRequest:-1,reconnect:true,maxStreamingLength:10000000,lastIndex:0,logLevel:"info",requestCount:0,fallbackMethod:"GET",fallbackTransport:"streaming",transport:"long-polling",webSocketImpl:null,webSocketBinaryType:null,dispatchUrl:null,webSocketPathDelimiter:"@@",enableXDR:false,rewriteURL:false,attachHeadersAsQueryString:true,executeCallbackBeforeReconnect:false,readyState:0,lastTimestamp:0,withCredentials:false,trackMessageLength:false,messageDelimiter:"|",connectTimeout:-1,reconnectInterval:0,dropHeaders:true,uuid:0,async:true,shared:false,readResponsesHeaders:false,maxReconnectOnClose:5,enableProtocol:true,pollingInterval:0,onError:function(aA){},onClose:function(aA){},onOpen:function(aA){},onMessage:function(aA){},onReopen:function(aB,aA){},onReconnect:function(aB,aA){},onMessagePublished:function(aA){},onTransportFailure:function(aB,aA){},onLocalMessage:function(aA){},onFailureToReconnect:function(aB,aA){},onClientTimeout:function(aA){}};
-var W={status:200,reasonPhrase:"OK",responseBody:"",messages:[],headers:[],state:"messageReceived",transport:"polling",error:null,request:null,partialMessage:"",errorHandled:false,closedByClientTimeout:false};
-var Z=null;
-var o=null;
-var v=null;
-var E=null;
-var G=null;
-var ak=true;
-var l=0;
-var aw=false;
-var aa=null;
-var aq;
-var q=null;
-var J=a.util.now();
-var K;
-var az;
-ay(M);
-function ar(){ak=true;
-aw=false;
-l=0;
-Z=null;
-o=null;
-v=null;
-E=null
-}function A(){am();
-ar()
-}function L(aB,aA){if(W.partialMessage===""&&(aA.transport==="streaming")&&(aB.responseText.length>aA.maxStreamingLength)){W.messages=[];
-aA.reconnectingOnLength=true;
-aA.isReopen=true;
-ai(true);
-D();
-am();
-R(aB,aA,aA.pollingInterval)
-}}function D(){if(O.enableProtocol&&!O.firstMessage){var aC="X-Atmosphere-Transport=close&X-Atmosphere-tracking-id="+O.uuid;
-a.util.each(O.headers,function(aE,aG){var aF=a.util.isFunction(aG)?aG.call(this,O,O,W):aG;
-if(aF!=null){aC+="&"+encodeURIComponent(aE)+"="+encodeURIComponent(aF)
-}});
-var aA=O.url.replace(/([?&])_=[^&]*/,aC);
-aA=aA+(aA===O.url?(/\?/.test(O.url)?"&":"?")+aC:"");
-var aB={connected:false};
-var aD=new a.AtmosphereRequest(aB);
-aD.attachHeadersAsQueryString=false;
-aD.dropHeaders=true;
-aD.url=aA;
-aD.contentType="text/plain";
-aD.transport="polling";
-aD.method="GET";
-aD.data="";
-aD.async=false;
-n("",aD)
-}}function an(){if(O.reconnectId){clearTimeout(O.reconnectId);
-delete O.reconnectId
-}O.reconnect=false;
-aw=true;
-W.request=O;
-W.state="unsubscribe";
-W.responseBody="";
-W.status=408;
-W.partialMessage="";
-C();
-D();
-am()
-}function am(){W.partialMessage="";
-if(O.id){clearTimeout(O.id)
-}if(E!=null){E.close();
-E=null
-}if(G!=null){G.abort();
-G=null
-}if(v!=null){v.abort();
-v=null
-}if(Z!=null){if(Z.canSendMessage){Z.close()
-}Z=null
-}if(o!=null){o.close();
-o=null
-}at()
-}function at(){if(aq!=null){clearInterval(K);
-document.cookie=az+"=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
-aq.signal("close",{reason:"",heir:!aw?J:(aq.get("children")||[])[0]});
-aq.close()
-}if(q!=null){q.close()
-}}function ay(aA){A();
-O=a.util.extend(O,aA);
-O.mrequest=O.reconnect;
-if(!O.reconnect){O.reconnect=true
-}}function p(){return O.webSocketImpl!=null||window.WebSocket||window.MozWebSocket
-}function S(){return window.EventSource
-}function t(){if(O.shared){q=ah(O);
-if(q!=null){if(O.logLevel==="debug"){a.util.debug("Storage service available. All communication will be local")
-}if(q.open(O)){return
-}}if(O.logLevel==="debug"){a.util.debug("No Storage service available.")
-}q=null
-}O.firstMessage=e==0?true:false;
-O.isOpen=false;
-O.ctime=a.util.now();
-if(O.uuid===0){O.uuid=e
-}W.closedByClientTimeout=false;
-if(O.transport!=="websocket"&&O.transport!=="sse"){s(O)
-}else{if(O.transport==="websocket"){if(!p()){Q("Websocket is not supported, using request.fallbackTransport ("+O.fallbackTransport+")")
-}else{aj(false)
-}}else{if(O.transport==="sse"){if(!S()){Q("Server Side Events(SSE) is not supported, using request.fallbackTransport ("+O.fallbackTransport+")")
-}else{I(false)
-}}}}}function ah(aE){var aF,aD,aI,aA="atmosphere-"+aE.url,aB={storage:function(){function aJ(aN){if(aN.key===aA&&aN.newValue){aC(aN.newValue)
-}}if(!a.util.storage){return
-}var aM=window.localStorage,aK=function(aN){return a.util.parseJSON(aM.getItem(aA+"-"+aN))
-},aL=function(aN,aO){aM.setItem(aA+"-"+aN,a.util.stringifyJSON(aO))
-};
-return{init:function(){aL("children",aK("children").concat([J]));
-a.util.on(window,"storage",aJ);
-return aK("opened")
-},signal:function(aN,aO){aM.setItem(aA,a.util.stringifyJSON({target:"p",type:aN,data:aO}))
-},close:function(){var aN=aK("children");
-a.util.off(window,"storage",aJ);
-if(aN){if(aG(aN,aE.id)){aL("children",aN)
-}}}}
-},windowref:function(){var aJ=window.open("",aA.replace(/\W/g,""));
-if(!aJ||aJ.closed||!aJ.callbacks){return
-}return{init:function(){aJ.callbacks.push(aC);
-aJ.children.push(J);
-return aJ.opened
-},signal:function(aK,aL){if(!aJ.closed&&aJ.fire){aJ.fire(a.util.stringifyJSON({target:"p",type:aK,data:aL}))
-}},close:function(){if(!aI){aG(aJ.callbacks,aC);
-aG(aJ.children,J)
-}}}
-}};
-function aG(aM,aL){var aJ,aK=aM.length;
-for(aJ=0;
-aJ<aK;
-aJ++){if(aM[aJ]===aL){aM.splice(aJ,1)
-}}return aK!==aM.length
-}function aC(aJ){var aL=a.util.parseJSON(aJ),aK=aL.data;
-if(aL.target==="c"){switch(aL.type){case"open":N("opening","local",O);
-break;
-case"close":if(!aI){aI=true;
-if(aK.reason==="aborted"){an()
-}else{if(aK.heir===J){t()
-}else{setTimeout(function(){t()
-},100)
-}}}break;
-case"message":F(aK,"messageReceived",200,aE.transport);
-break;
-case"localMessage":ac(aK);
-break
-}}}function aH(){var aJ=new RegExp("(?:^|; )("+encodeURIComponent(aA)+")=([^;]*)").exec(document.cookie);
-if(aJ){return a.util.parseJSON(decodeURIComponent(aJ[2]))
-}}aF=aH();
-if(!aF||a.util.now()-aF.ts>1000){return
-}aD=aB.storage()||aB.windowref();
-if(!aD){return
-}return{open:function(){var aJ;
-K=setInterval(function(){var aK=aF;
-aF=aH();
-if(!aF||aK.ts===aF.ts){aC(a.util.stringifyJSON({target:"c",type:"close",data:{reason:"error",heir:aK.heir}}))
-}},1000);
-aJ=aD.init();
-if(aJ){setTimeout(function(){N("opening","local",aE)
-},50)
-}return aJ
-},send:function(aJ){aD.signal("send",aJ)
-},localSend:function(aJ){aD.signal("localSend",a.util.stringifyJSON({id:J,event:aJ}))
-},close:function(){if(!aw){clearInterval(K);
-aD.signal("close");
-aD.close()
-}}}
-}function ad(){var aB,aA="atmosphere-"+O.url,aF={storage:function(){function aG(aI){if(aI.key===aA&&aI.newValue){aC(aI.newValue)
-}}if(!a.util.storage){return
-}var aH=window.localStorage;
-return{init:function(){a.util.on(window,"storage",aG)
-},signal:function(aI,aJ){aH.setItem(aA,a.util.stringifyJSON({target:"c",type:aI,data:aJ}))
-},get:function(aI){return a.util.parseJSON(aH.getItem(aA+"-"+aI))
-},set:function(aI,aJ){aH.setItem(aA+"-"+aI,a.util.stringifyJSON(aJ))
-},close:function(){a.util.off(window,"storage",aG);
-aH.removeItem(aA);
-aH.removeItem(aA+"-opened");
-aH.removeItem(aA+"-children")
-}}
-},windowref:function(){var aH=aA.replace(/\W/g,""),aG=document.getElementById(aH),aI;
-if(!aG){aG=document.createElement("div");
-aG.id=aH;
-aG.style.display="none";
-aG.innerHTML='<iframe name="'+aH+'" />';
-document.body.appendChild(aG)
-}aI=aG.firstChild.contentWindow;
-return{init:function(){aI.callbacks=[aC];
-aI.fire=function(aJ){var aK;
-for(aK=0;
-aK<aI.callbacks.length;
-aK++){aI.callbacks[aK](aJ)
-}}
-},signal:function(aJ,aK){if(!aI.closed&&aI.fire){aI.fire(a.util.stringifyJSON({target:"c",type:aJ,data:aK}))
-}},get:function(aJ){return !aI.closed?aI[aJ]:null
-},set:function(aJ,aK){if(!aI.closed){aI[aJ]=aK
-}},close:function(){}}
-}};
-function aC(aG){var aI=a.util.parseJSON(aG),aH=aI.data;
-if(aI.target==="p"){switch(aI.type){case"send":al(aH);
-break;
-case"localSend":ac(aH);
-break;
-case"close":an();
-break
-}}}aa=function aE(aG){aB.signal("message",aG)
-};
-function aD(){document.cookie=az+"="+encodeURIComponent(a.util.stringifyJSON({ts:a.util.now()+1,heir:(aB.get("children")||[])[0]}))+"; path=/"
-}aB=aF.storage()||aF.windowref();
-aB.init();
-if(O.logLevel==="debug"){a.util.debug("Installed StorageService "+aB)
-}aB.set("children",[]);
-if(aB.get("opened")!=null&&!aB.get("opened")){aB.set("opened",false)
-}az=encodeURIComponent(aA);
-aD();
-K=setInterval(aD,1000);
-aq=aB
-}function N(aC,aF,aB){if(O.shared&&aF!=="local"){ad()
-}if(aq!=null){aq.set("opened",true)
-}aB.close=function(){an()
-};
-if(l>0&&aC==="re-connecting"){aB.isReopen=true;
-ae(W)
-}else{if(W.error==null){W.request=aB;
-var aD=W.state;
-W.state=aC;
-var aA=W.transport;
-W.transport=aF;
-var aE=W.responseBody;
-C();
-W.responseBody=aE;
-W.state=aD;
-W.transport=aA
-}}}function z(aC){aC.transport="jsonp";
-var aB=O,aA;
-if((aC!=null)&&(typeof(aC)!=="undefined")){aB=aC
-}G={open:function(){var aE="atmosphere"+(++J);
-function aD(){var aF=aB.url;
-if(aB.dispatchUrl!=null){aF+=aB.dispatchUrl
-}var aH=aB.data;
-if(aB.attachHeadersAsQueryString){aF=X(aB);
-if(aH!==""){aF+="&X-Atmosphere-Post-Body="+encodeURIComponent(aH)
-}aH=""
-}var aG=document.head||document.getElementsByTagName("head")[0]||document.documentElement;
-aA=document.createElement("script");
-aA.src=aF+"&jsonpTransport="+aE;
-aA.clean=function(){aA.clean=aA.onerror=aA.onload=aA.onreadystatechange=null;
-if(aA.parentNode){aA.parentNode.removeChild(aA)
-}};
-aA.onload=aA.onreadystatechange=function(){if(!aA.readyState||/loaded|complete/.test(aA.readyState)){aA.clean()
-}};
-aA.onerror=function(){aA.clean();
-aB.lastIndex=0;
-if(aB.openId){clearTimeout(aB.openId)
-}if(aB.reconnect&&l++<aB.maxReconnectOnClose){N("re-connecting",aB.transport,aB);
-R(G,aB,aC.reconnectInterval);
-aB.openId=setTimeout(function(){ao(aB)
-},aB.reconnectInterval+1000)
-}else{af(0,"maxReconnectOnClose reached")
-}};
-aG.insertBefore(aA,aG.firstChild)
-}window[aE]=function(aH){if(aB.reconnect){if(aB.maxRequest===-1||aB.requestCount++<aB.maxRequest){if(!aB.executeCallbackBeforeReconnect){R(G,aB,aB.pollingInterval)
-}if(aH!=null&&typeof aH!=="string"){try{aH=aH.message
-}catch(aG){}}var aF=x(aH,aB,W);
-if(!aF){F(W.responseBody,"messageReceived",200,aB.transport)
-}if(aB.executeCallbackBeforeReconnect){R(G,aB,aB.pollingInterval)
-}}else{a.util.log(O.logLevel,["JSONP reconnect maximum try reached "+O.requestCount]);
-af(0,"maxRequest reached")
-}}};
-setTimeout(function(){aD()
-},50)
-},abort:function(){if(aA&&aA.clean){aA.clean()
-}}};
-G.open()
-}function j(aA){if(O.webSocketImpl!=null){return O.webSocketImpl
-}else{if(window.WebSocket){return new WebSocket(aA)
-}else{return new MozWebSocket(aA)
-}}}function k(){return X(O,a.util.getAbsoluteURL(O.url)).replace(/^http/,"ws")
-}function ax(){var aA=X(O);
-return aA
-}function I(aB){W.transport="sse";
-var aA=ax();
-if(O.logLevel==="debug"){a.util.debug("Invoking executeSSE");
-a.util.debug("Using URL: "+aA)
-}if(O.enableProtocol&&aB){var aD=a.util.now()-O.ctime;
-O.lastTimestamp=Number(O.stime)+Number(aD)
-}if(aB&&!O.reconnect){if(o!=null){am()
-}return
-}try{o=new EventSource(aA,{withCredentials:O.withCredentials})
-}catch(aC){af(0,aC);
-Q("SSE failed. Downgrading to fallback transport and resending");
-return
-}if(O.connectTimeout>0){O.id=setTimeout(function(){if(!aB){am()
-}},O.connectTimeout)
-}o.onopen=function(aE){y(O);
-if(O.logLevel==="debug"){a.util.debug("SSE successfully opened")
-}if(!O.enableProtocol){if(!aB){N("opening","sse",O)
-}else{N("re-opening","sse",O)
-}}else{if(O.isReopen){O.isReopen=false;
-N("re-opening",O.transport,O)
-}}aB=true;
-if(O.method==="POST"){W.state="messageReceived";
-o.send(O.data)
-}};
-o.onmessage=function(aF){y(O);
-if(!O.enableXDR&&aF.origin&&aF.origin!==window.location.protocol+"//"+window.location.host){a.util.log(O.logLevel,["Origin was not "+window.location.protocol+"//"+window.location.host]);
-return
-}W.state="messageReceived";
-W.status=200;
-aF=aF.data;
-var aE=x(aF,O,W);
-if(!aE){C();
-W.responseBody="";
-W.messages=[]
-}};
-o.onerror=function(aE){clearTimeout(O.id);
-if(W.closedByClientTimeout){return
-}ai(aB);
-am();
-if(aw){a.util.log(O.logLevel,["SSE closed normally"])
-}else{if(!aB){Q("SSE failed. Downgrading to fallback transport and resending")
-}else{if(O.reconnect&&(W.transport==="sse")){if(l++<O.maxReconnectOnClose){N("re-connecting",O.transport,O);
-if(O.reconnectInterval>0){O.reconnectId=setTimeout(function(){I(true)
-},O.reconnectInterval)
-}else{I(true)
-}W.responseBody="";
-W.messages=[]
-}else{a.util.log(O.logLevel,["SSE reconnect maximum try reached "+l]);
-af(0,"maxReconnectOnClose reached")
-}}}}}
-}function aj(aB){W.transport="websocket";
-if(O.enableProtocol&&aB){var aE=a.util.now()-O.ctime;
-O.lastTimestamp=Number(O.stime)+Number(aE)
-}var aA=k(O.url);
-if(O.logLevel==="debug"){a.util.debug("Invoking executeWebSocket");
-a.util.debug("Using URL: "+aA)
-}if(aB&&!O.reconnect){if(Z!=null){am()
-}return
-}Z=j(aA);
-if(O.webSocketBinaryType!=null){Z.binaryType=O.webSocketBinaryType
-}if(O.connectTimeout>0){O.id=setTimeout(function(){if(!aB){var aF={code:1002,reason:"",wasClean:false};
-Z.onclose(aF);
-try{am()
-}catch(aG){}return
-}},O.connectTimeout)
-}Z.onopen=function(aG){y(O);
-if(O.logLevel==="debug"){a.util.debug("Websocket successfully opened")
-}var aF=aB;
-if(Z!=null){Z.canSendMessage=true
-}if(!O.enableProtocol){aB=true;
-if(aF){N("re-opening","websocket",O)
-}else{N("opening","websocket",O)
-}}if(Z!=null){if(O.method==="POST"){W.state="messageReceived";
-Z.send(O.data)
-}}};
-Z.onmessage=function(aH){y(O);
-if(O.enableProtocol){aB=true
-}W.state="messageReceived";
-W.status=200;
-aH=aH.data;
-var aF=typeof(aH)==="string";
-if(aF){var aG=x(aH,O,W);
-if(!aG){C();
-W.responseBody="";
-W.messages=[]
-}}else{if(!u(O,aH)){return
-}W.responseBody=aH;
-C();
-W.responseBody=null
-}};
-Z.onerror=function(aF){clearTimeout(O.id)
-};
-Z.onclose=function(aF){clearTimeout(O.id);
-if(W.state==="closed"){return
-}var aG=aF.reason;
-if(aG===""){switch(aF.code){case 1000:aG="Normal closure; the connection successfully completed whatever purpose for which it was created.";
-break;
-case 1001:aG="The endpoint is going away, either because of a server failure or because the browser is navigating away from the page that opened the connection.";
-break;
-case 1002:aG="The endpoint is terminating the connection due to a protocol error.";
-break;
-case 1003:aG="The connection is being terminated because the endpoint received data of a type it cannot accept (for example, a text-only endpoint received binary data).";
-break;
-case 1004:aG="The endpoint is terminating the connection because a data frame was received that is too large.";
-break;
-case 1005:aG="Unknown: no status code was provided even though one was expected.";
-break;
-case 1006:aG="Connection was closed abnormally (that is, with no close frame being sent).";
-break
-}}if(O.logLevel==="warn"){a.util.warn("Websocket closed, reason: "+aG);
-a.util.warn("Websocket closed, wasClean: "+aF.wasClean)
-}if(W.closedByClientTimeout){return
-}ai(aB);
-W.state="closed";
-if(aw){a.util.log(O.logLevel,["Websocket closed normally"])
-}else{if(!aB){Q("Websocket failed. Downgrading to Comet and resending")
-}else{if(O.reconnect&&W.transport==="websocket"){am();
-if(l++<O.maxReconnectOnClose){N("re-connecting",O.transport,O);
-if(O.reconnectInterval>0){O.reconnectId=setTimeout(function(){W.responseBody="";
-W.messages=[];
-aj(true)
-},O.reconnectInterval)
-}else{W.responseBody="";
-W.messages=[];
-aj(true)
-}}else{a.util.log(O.logLevel,["Websocket reconnect maximum try reached "+O.requestCount]);
-if(O.logLevel==="warn"){a.util.warn("Websocket error, reason: "+aF.reason)
-}af(0,"maxReconnectOnClose reached")
-}}}}};
-var aC=navigator.userAgent.toLowerCase();
-var aD=aC.indexOf("android")>-1;
-if(aD&&Z.url===undefined){Z.onclose({reason:"Android 4.1 does not support websockets.",wasClean:false})
-}}function u(aD,aC){var aA=true;
-if(aD.transport==="polling"){return aA
-}if(a.util.trim(aC).length!==0&&aD.enableProtocol&&aD.firstMessage){aD.firstMessage=false;
-var aB=aC.split(aD.messageDelimiter);
-var aE=aB.length===2?0:1;
-aD.uuid=a.util.trim(aB[aE]);
-aD.stime=a.util.trim(aB[aE+1]);
-aA=false;
-if(aD.transport!=="long-polling"){ao(aD)
-}e=aD.uuid
-}else{if(aD.enableProtocol&&aD.firstMessage){aA=false
-}else{ao(aD)
-}}return aA
-}function y(aA){clearTimeout(aA.id);
-if(aA.timeout>0&&aA.transport!=="polling"){aA.id=setTimeout(function(){r(aA);
-D();
-am()
-},aA.timeout)
-}}function r(aA){W.closedByClientTimeout=true;
-W.state="closedByClient";
-W.responseBody="";
-W.status=408;
-W.messages=[];
-C()
-}function af(aA,aB){am();
-clearTimeout(O.id);
-W.state="error";
-W.reasonPhrase=aB;
-W.responseBody="";
-W.status=aA;
-W.messages=[];
-C()
-}function x(aE,aD,aA){if(!u(aD,aE)){return true
-}if(aE.length===0){return true
-}if(aD.trackMessageLength){aE=aA.partialMessage+aE;
-var aC=[];
-var aB=aE.indexOf(aD.messageDelimiter);
-while(aB!==-1){var aG=a.util.trim(aE.substring(0,aB));
-var aF=+aG;
-if(isNaN(aF)){throw new Error('message length "'+aG+'" is not a number')
-}aB+=aD.messageDelimiter.length;
-if(aB+aF>aE.length){aB=-1
-}else{aC.push(aE.substring(aB,aB+aF));
-aE=aE.substring(aB+aF,aE.length);
-aB=aE.indexOf(aD.messageDelimiter)
-}}aA.partialMessage=aE;
-if(aC.length!==0){aA.responseBody=aC.join(aD.messageDelimiter);
-aA.messages=aC;
-return false
-}else{aA.responseBody="";
-aA.messages=[];
-return true
-}}else{aA.responseBody=aE
-}return false
-}function Q(aA){a.util.log(O.logLevel,[aA]);
-if(typeof(O.onTransportFailure)!=="undefined"){O.onTransportFailure(aA,O)
-}else{if(typeof(a.util.onTransportFailure)!=="undefined"){a.util.onTransportFailure(aA,O)
-}}O.transport=O.fallbackTransport;
-var aB=O.connectTimeout===-1?0:O.connectTimeout;
-if(O.reconnect&&O.transport!=="none"||O.transport==null){O.method=O.fallbackMethod;
-W.transport=O.fallbackTransport;
-O.fallbackTransport="none";
-if(aB>0){O.reconnectId=setTimeout(function(){t()
-},aB)
-}else{t()
-}}else{af(500,"Unable to reconnect with fallback transport")
-}}function X(aC,aA){var aB=O;
-if((aC!=null)&&(typeof(aC)!=="undefined")){aB=aC
-}if(aA==null){aA=aB.url
-}if(!aB.attachHeadersAsQueryString){return aA
-}if(aA.indexOf("X-Atmosphere-Framework")!==-1){return aA
-}aA+=(aA.indexOf("?")!==-1)?"&":"?";
-aA+="X-Atmosphere-tracking-id="+aB.uuid;
-aA+="&X-Atmosphere-Framework="+c;
-aA+="&X-Atmosphere-Transport="+aB.transport;
-if(aB.trackMessageLength){aA+="&X-Atmosphere-TrackMessageSize=true"
-}if(aB.lastTimestamp!=null){aA+="&X-Cache-Date="+aB.lastTimestamp
-}else{aA+="&X-Cache-Date="+0
-}if(aB.contentType!==""){aA+="&Content-Type="+(aB.transport==="websocket"?aB.contentType:encodeURIComponent(aB.contentType))
-}if(aB.enableProtocol){aA+="&X-atmo-protocol=true"
-}a.util.each(aB.headers,function(aD,aF){var aE=a.util.isFunction(aF)?aF.call(this,aB,aC,W):aF;
-if(aE!=null){aA+="&"+encodeURIComponent(aD)+"="+encodeURIComponent(aE)
-}});
-return aA
-}function ao(aA){if(!aA.isOpen){aA.isOpen=true;
-N("opening",aA.transport,aA)
-}else{if(aA.isReopen){aA.isReopen=false;
-N("re-opening",aA.transport,aA)
-}}}function s(aC){var aA=O;
-if((aC!=null)||(typeof(aC)!=="undefined")){aA=aC
-}aA.lastIndex=0;
-aA.readyState=0;
-if((aA.transport==="jsonp")||((aA.enableXDR)&&(a.util.checkCORSSupport()))){z(aA);
-return
-}if(a.util.browser.msie&&+a.util.browser.version.split(".")[0]<10){if((aA.transport==="streaming")){if(aA.enableXDR&&window.XDomainRequest){P(aA)
-}else{av(aA)
-}return
-}if((aA.enableXDR)&&(window.XDomainRequest)){P(aA);
-return
-}}var aD=function(){aA.lastIndex=0;
-if(aA.reconnect&&l++<aA.maxReconnectOnClose){N("re-connecting",aC.transport,aC);
-R(aB,aA,aC.reconnectInterval)
-}else{af(0,"maxReconnectOnClose reached")
-}};
-if(aA.force||(aA.reconnect&&(aA.maxRequest===-1||aA.requestCount++<aA.maxRequest))){aA.force=false;
-var aB=a.util.xhr();
-aB.hasData=false;
-h(aB,aA,true);
-if(aA.suspend){v=aB
-}if(aA.transport!=="polling"){W.transport=aA.transport;
-aB.onabort=function(){ai(true)
-};
-aB.onerror=function(){W.error=true;
-try{W.status=XMLHttpRequest.status
-}catch(aF){W.status=500
-}if(!W.status){W.status=500
-}if(!W.errorHandled){am();
-aD()
-}}
-}aB.onreadystatechange=function(){if(aw){return
-}W.error=null;
-var aG=false;
-var aL=false;
-if(aA.transport==="streaming"&&aA.readyState>2&&aB.readyState===4){if(aA.reconnectingOnLength){return
-}am();
-aD();
-return
-}aA.readyState=aB.readyState;
-if(aA.transport==="streaming"&&aB.readyState>=3){aL=true
-}else{if(aA.transport==="long-polling"&&aB.readyState===4){aL=true
-}}y(O);
-if(aA.transport!=="polling"){var aF=200;
-if(aB.readyState===4){aF=aB.status>1000?0:aB.status
-}if(aF>=300||aF===0){W.errorHandled=true;
-am();
-aD();
-return
-}if((!aA.enableProtocol||!aC.firstMessage)&&aB.readyState===2){ao(aA)
-}}else{if(aB.readyState===4){aL=true
-}}if(aL){var aJ=aB.responseText;
-if(a.util.trim(aJ).length===0&&aA.transport==="long-polling"){if(!aB.hasData){R(aB,aA,aA.pollingInterval)
-}else{aB.hasData=false
-}return
-}aB.hasData=true;
-ag(aB,O);
-if(aA.transport==="streaming"){if(!a.util.browser.opera){var aI=aJ.substring(aA.lastIndex,aJ.length);
-aG=x(aI,aA,W);
-aA.lastIndex=aJ.length;
-if(aG){return
-}}else{a.util.iterate(function(){if(W.status!==500&&aB.responseText.length>aA.lastIndex){try{W.status=aB.status;
-W.headers=a.util.parseHeaders(aB.getAllResponseHeaders());
-ag(aB,O)
-}catch(aN){W.status=404
-}y(O);
-W.state="messageReceived";
-var aM=aB.responseText.substring(aA.lastIndex);
-aA.lastIndex=aB.responseText.length;
-aG=x(aM,aA,W);
-if(!aG){C()
-}L(aB,aA)
-}else{if(W.status>400){aA.lastIndex=aB.responseText.length;
-return false
-}}},0)
-}}else{aG=x(aJ,aA,W)
-}try{W.status=aB.status;
-W.headers=a.util.parseHeaders(aB.getAllResponseHeaders());
-ag(aB,aA)
-}catch(aK){W.status=404
-}if(aA.suspend){W.state=W.status===0?"closed":"messageReceived"
-}else{W.state="messagePublished"
-}var aH=aC.transport!=="streaming"&&aC.transport!=="polling";
-if(aH&&!aA.executeCallbackBeforeReconnect){R(aB,aA,aA.pollingInterval)
-}if(W.responseBody.length!==0&&!aG){C()
-}if(aH&&aA.executeCallbackBeforeReconnect){R(aB,aA,aA.pollingInterval)
-}L(aB,aA)
-}};
-try{aB.send(aA.data);
-ak=true
-}catch(aE){a.util.log(aA.logLevel,["Unable to connect to "+aA.url]);
-af(0,aE)
-}}else{if(aA.logLevel==="debug"){a.util.log(aA.logLevel,["Max re-connection reached."])
-}af(0,"maxRequest reached")
-}}function h(aC,aD,aB){var aA=aD.url;
-if(aD.dispatchUrl!=null&&aD.method==="POST"){aA+=aD.dispatchUrl
-}aA=X(aD,aA);
-aA=a.util.prepareURL(aA);
-if(aB){aC.open(aD.method,aA,aD.async);
-if(aD.connectTimeout>0){aD.id=setTimeout(function(){if(aD.requestCount===0){am();
-F("Connect timeout","closed",200,aD.transport)
-}},aD.connectTimeout)
-}}if(O.withCredentials){if("withCredentials" in aC){aC.withCredentials=true
-}}if(!O.dropHeaders){aC.setRequestHeader("X-Atmosphere-Framework",a.util.version);
-aC.setRequestHeader("X-Atmosphere-Transport",aD.transport);
-if(aD.lastTimestamp!=null){aC.setRequestHeader("X-Cache-Date",aD.lastTimestamp)
-}else{aC.setRequestHeader("X-Cache-Date",0)
-}if(aD.trackMessageLength){aC.setRequestHeader("X-Atmosphere-TrackMessageSize","true")
-}aC.setRequestHeader("X-Atmosphere-tracking-id",aD.uuid);
-a.util.each(aD.headers,function(aE,aG){var aF=a.util.isFunction(aG)?aG.call(this,aC,aD,aB,W):aG;
-if(aF!=null){aC.setRequestHeader(aE,aF)
-}})
-}if(aD.contentType!==""){aC.setRequestHeader("Content-Type",aD.contentType)
-}}function R(aB,aC,aD){if(aC.reconnect||(aC.suspend&&ak)){var aA=0;
-if(aB&&aB.readyState>1){aA=aB.status>1000?0:aB.status
-}W.status=aA===0?204:aA;
-W.reason=aA===0?"Server resumed the connection or down.":"OK";
-clearTimeout(aC.id);
-if(aC.reconnectId){clearTimeout(aC.reconnectId);
-delete aC.reconnectId
-}if(aD>0){O.reconnectId=setTimeout(function(){s(aC)
-},aD)
-}else{s(aC)
-}}}function ae(aA){aA.state="re-connecting";
-ab(aA)
-}function P(aA){if(aA.transport!=="polling"){E=V(aA);
-E.open()
-}else{V(aA).open()
-}}function V(aC){var aB=O;
-if((aC!=null)&&(typeof(aC)!=="undefined")){aB=aC
-}var aH=aB.transport;
-var aG=0;
-var aA=new window.XDomainRequest();
-var aE=function(){if(aB.transport==="long-polling"&&(aB.reconnect&&(aB.maxRequest===-1||aB.requestCount++<aB.maxRequest))){aA.status=200;
-P(aB)
-}};
-var aF=aB.rewriteURL||function(aJ){var aI=/(?:^|;\s*)(JSESSIONID|PHPSESSID)=([^;]*)/.exec(document.cookie);
-switch(aI&&aI[1]){case"JSESSIONID":return aJ.replace(/;jsessionid=[^\?]*|(\?)|$/,";jsessionid="+aI[2]+"$1");
-case"PHPSESSID":return aJ.replace(/\?PHPSESSID=[^&]*&?|\?|$/,"?PHPSESSID="+aI[2]+"&").replace(/&$/,"")
-}return aJ
-};
-aA.onprogress=function(){aD(aA)
-};
-aA.onerror=function(){if(aB.transport!=="polling"){am();
-if(l++<aB.maxReconnectOnClose){if(aB.reconnectInterval>0){aB.reconnectId=setTimeout(function(){N("re-connecting",aC.transport,aC);
-P(aB)
-},aB.reconnectInterval)
-}else{N("re-connecting",aC.transport,aC);
-P(aB)
-}}else{af(0,"maxReconnectOnClose reached")
-}}};
-aA.onload=function(){};
-var aD=function(aI){clearTimeout(aB.id);
-var aK=aI.responseText;
-aK=aK.substring(aG);
-aG+=aK.length;
-if(aH!=="polling"){y(aB);
-var aJ=x(aK,aB,W);
-if(aH==="long-polling"&&a.util.trim(aK).length===0){return
-}if(aB.executeCallbackBeforeReconnect){aE()
-}if(!aJ){F(W.responseBody,"messageReceived",200,aH)
-}if(!aB.executeCallbackBeforeReconnect){aE()
-}}};
-return{open:function(){var aI=aB.url;
-if(aB.dispatchUrl!=null){aI+=aB.dispatchUrl
-}aI=X(aB,aI);
-aA.open(aB.method,aF(aI));
-if(aB.method==="GET"){aA.send()
-}else{aA.send(aB.data)
-}if(aB.connectTimeout>0){aB.id=setTimeout(function(){if(aB.requestCount===0){am();
-F("Connect timeout","closed",200,aB.transport)
-}},aB.connectTimeout)
-}},close:function(){aA.abort()
-}}
-}function av(aA){E=w(aA);
-E.open()
-}function w(aD){var aC=O;
-if((aD!=null)&&(typeof(aD)!=="undefined")){aC=aD
-}var aB;
-var aE=new window.ActiveXObject("htmlfile");
-aE.open();
-aE.close();
-var aA=aC.url;
-if(aC.dispatchUrl!=null){aA+=aC.dispatchUrl
-}if(aC.transport!=="polling"){W.transport=aC.transport
-}return{open:function(){var aF=aE.createElement("iframe");
-aA=X(aC);
-if(aC.data!==""){aA+="&X-Atmosphere-Post-Body="+encodeURIComponent(aC.data)
-}aA=a.util.prepareURL(aA);
-aF.src=aA;
-aE.body.appendChild(aF);
-var aG=aF.contentDocument||aF.contentWindow.document;
-aB=a.util.iterate(function(){try{if(!aG.firstChild){return
-}var aJ=aG.body?aG.body.lastChild:aG;
-var aL=function(){var aN=aJ.cloneNode(true);
-aN.appendChild(aG.createTextNode("."));
-var aM=aN.innerText;
-aM=aM.substring(0,aM.length-1);
-return aM
-};
-if(!aG.body||!aG.body.firstChild||aG.body.firstChild.nodeName.toLowerCase()!=="pre"){var aI=aG.head||aG.getElementsByTagName("head")[0]||aG.documentElement||aG;
-var aH=aG.createElement("script");
-aH.text="document.write('<plaintext>')";
-aI.insertBefore(aH,aI.firstChild);
-aI.removeChild(aH);
-aJ=aG.body.lastChild
-}if(aC.closed){aC.isReopen=true
-}aB=a.util.iterate(function(){var aN=aL();
-if(aN.length>aC.lastIndex){y(O);
-W.status=200;
-W.error=null;
-aJ.innerText="";
-var aM=x(aN,aC,W);
-if(aM){return""
-}F(W.responseBody,"messageReceived",200,aC.transport)
-}aC.lastIndex=0;
-if(aG.readyState==="complete"){ai(true);
-N("re-connecting",aC.transport,aC);
-if(aC.reconnectInterval>0){aC.reconnectId=setTimeout(function(){av(aC)
-},aC.reconnectInterval)
-}else{av(aC)
-}return false
-}},null);
-return false
-}catch(aK){W.error=true;
-N("re-connecting",aC.transport,aC);
-if(l++<aC.maxReconnectOnClose){if(aC.reconnectInterval>0){aC.reconnectId=setTimeout(function(){av(aC)
-},aC.reconnectInterval)
-}else{av(aC)
-}}else{af(0,"maxReconnectOnClose reached")
-}aE.execCommand("Stop");
-aE.close();
-return false
-}})
-},close:function(){if(aB){aB()
-}aE.execCommand("Stop");
-ai(true)
-}}
-}function al(aA){if(q!=null){m(aA)
-}else{if(v!=null||o!=null){i(aA)
-}else{if(E!=null){Y(aA)
-}else{if(G!=null){U(aA)
-}else{if(Z!=null){H(aA)
-}else{af(0,"No suspended connection available");
-a.util.error("No suspended connection available. Make sure atmosphere.subscribe has been called and request.onOpen invoked before invoking this method")
-}}}}}}function n(aB,aA){if(!aA){aA=ap(aB)
-}aA.transport="polling";
-aA.method="GET";
-aA.async=false;
-aA.withCredentials=false;
-aA.reconnect=false;
-aA.force=true;
-aA.suspend=false;
-aA.timeout=1000;
-s(aA)
-}function m(aA){q.send(aA)
-}function B(aB){if(aB.length===0){return
-}try{if(q){q.localSend(aB)
-}else{if(aq){aq.signal("localMessage",a.util.stringifyJSON({id:J,event:aB}))
-}}}catch(aA){a.util.error(aA)
-}}function i(aB){var aA=ap(aB);
-s(aA)
-}function Y(aB){if(O.enableXDR&&a.util.checkCORSSupport()){var aA=ap(aB);
-aA.reconnect=false;
-z(aA)
-}else{i(aB)
-}}function U(aA){i(aA)
-}function T(aA){var aB=aA;
-if(typeof(aB)==="object"){aB=aA.data
-}return aB
-}function ap(aB){var aC=T(aB);
-var aA={connected:false,timeout:60000,method:"POST",url:O.url,contentType:O.contentType,headers:O.headers,reconnect:true,callback:null,data:aC,suspend:false,maxRequest:-1,logLevel:"info",requestCount:0,withCredentials:O.withCredentials,async:O.async,transport:"polling",isOpen:true,attachHeadersAsQueryString:true,enableXDR:O.enableXDR,uuid:O.uuid,dispatchUrl:O.dispatchUrl,enableProtocol:false,messageDelimiter:"|",maxReconnectOnClose:O.maxReconnectOnClose};
-if(typeof(aB)==="object"){aA=a.util.extend(aA,aB)
-}return aA
-}function H(aA){var aD=a.util.isBinary(aA)?aA:T(aA);
-var aB;
-try{if(O.dispatchUrl!=null){aB=O.webSocketPathDelimiter+O.dispatchUrl+O.webSocketPathDelimiter+aD
-}else{aB=aD
-}if(!Z.canSendMessage){a.util.error("WebSocket not connected.");
-return
-}Z.send(aB)
-}catch(aC){Z.onclose=function(aE){};
-am();
-Q("Websocket failed. Downgrading to Comet and resending "+aA);
-i(aA)
-}}function ac(aB){var aA=a.util.parseJSON(aB);
-if(aA.id!==J){if(typeof(O.onLocalMessage)!=="undefined"){O.onLocalMessage(aA.event)
-}else{if(typeof(a.util.onLocalMessage)!=="undefined"){a.util.onLocalMessage(aA.event)
-}}}}function F(aD,aA,aB,aC){W.responseBody=aD;
-W.transport=aC;
-W.status=aB;
-W.state=aA;
-C()
-}function ag(aA,aD){if(!aD.readResponsesHeaders){if(!aD.enableProtocol){aD.lastTimestamp=a.util.now();
-aD.uuid=J
-}}else{try{var aC=aA.getResponseHeader("X-Cache-Date");
-if(aC&&aC!=null&&aC.length>0){aD.lastTimestamp=aC.split(" ").pop()
-}var aB=aA.getResponseHeader("X-Atmosphere-tracking-id");
-if(aB&&aB!=null){aD.uuid=aB.split(" ").pop()
-}}catch(aE){}}}function ab(aA){au(aA,O);
-au(aA,a.util)
-}function au(aB,aC){switch(aB.state){case"messageReceived":l=0;
-if(typeof(aC.onMessage)!=="undefined"){aC.onMessage(aB)
-}break;
-case"error":if(typeof(aC.onError)!=="undefined"){aC.onError(aB)
-}break;
-case"opening":delete O.closed;
-if(typeof(aC.onOpen)!=="undefined"){aC.onOpen(aB)
-}break;
-case"messagePublished":if(typeof(aC.onMessagePublished)!=="undefined"){aC.onMessagePublished(aB)
-}break;
-case"re-connecting":if(typeof(aC.onReconnect)!=="undefined"){aC.onReconnect(O,aB)
-}break;
-case"closedByClient":if(typeof(aC.onClientTimeout)!=="undefined"){aC.onClientTimeout(O)
-}break;
-case"re-opening":delete O.closed;
-if(typeof(aC.onReopen)!=="undefined"){aC.onReopen(O,aB)
-}break;
-case"fail-to-reconnect":if(typeof(aC.onFailureToReconnect)!=="undefined"){aC.onFailureToReconnect(O,aB)
-}break;
-case"unsubscribe":case"closed":var aA=typeof(O.closed)!=="undefined"?O.closed:false;
-if(typeof(aC.onClose)!=="undefined"&&!aA){aC.onClose(aB)
-}O.closed=true;
-break
-}}function ai(aA){if(W.state!=="closed"){W.state="closed";
-W.responseBody="";
-W.messages=[];
-W.status=!aA?501:200;
-C()
-}}function C(){var aC=function(aF,aG){aG(W)
-};
-if(q==null&&aa!=null){aa(W.responseBody)
-}O.reconnect=O.mrequest;
-var aA=typeof(W.responseBody)==="string";
-var aD=(aA&&O.trackMessageLength)?(W.messages.length>0?W.messages:[""]):new Array(W.responseBody);
-for(var aB=0;
-aB<aD.length;
-aB++){if(aD.length>1&&aD[aB].length===0){continue
-}W.responseBody=(aA)?a.util.trim(aD[aB]):aD[aB];
-if(q==null&&aa!=null){aa(W.responseBody)
-}if(W.responseBody.length===0&&W.state==="messageReceived"){continue
-}ab(W);
-if(f.length>0){if(O.logLevel==="debug"){a.util.debug("Invoking "+f.length+" global callbacks: "+W.state)
-}try{a.util.each(f,aC)
-}catch(aE){a.util.log(O.logLevel,["Callback exception"+aE])
-}}if(typeof(O.callback)==="function"){if(O.logLevel==="debug"){a.util.debug("Invoking request callbacks")
-}try{O.callback(W)
-}catch(aE){a.util.log(O.logLevel,["Callback exception"+aE])
-}}}}this.subscribe=function(aA){ay(aA);
-t()
-};
-this.execute=function(){t()
-};
-this.close=function(){an()
-};
-this.disconnect=function(){D()
-};
-this.getUrl=function(){return O.url
-};
-this.push=function(aC,aB){if(aB!=null){var aA=O.dispatchUrl;
-O.dispatchUrl=aB;
-al(aC);
-O.dispatchUrl=aA
-}else{al(aC)
-}};
-this.getUUID=function(){return O.uuid
-};
-this.pushLocal=function(aA){B(aA)
-};
-this.enableProtocol=function(aA){return O.enableProtocol
-};
-this.request=O;
-this.response=W
-}};
-a.subscribe=function(h,k,j){if(typeof(k)==="function"){a.addCallback(k)
-}e=0;
-if(typeof(h)!=="string"){j=h
-}else{j.url=h
-}var i=new a.AtmosphereRequest(j);
-i.execute();
-g[g.length]=i;
-return i
-};
-a.unsubscribe=function(){if(g.length>0){var h=[].concat(g);
-for(var k=0;
-k<h.length;
-k++){var j=h[k];
-j.close();
-clearTimeout(j.response.request.id)
-}}g=[];
-f=[]
-};
-a.unsubscribeUrl=function(j){var h=-1;
-if(g.length>0){for(var l=0;
-l<g.length;
-l++){var k=g[l];
-if(k.getUrl()===j){k.close();
-clearTimeout(k.response.request.id);
-h=l;
-break
-}}}if(h>=0){g.splice(h,1)
-}};
-a.addCallback=function(h){if(a.util.inArray(h,f)===-1){f.push(h)
-}};
-a.removeCallback=function(i){var h=a.util.inArray(i,f);
-if(h!==-1){f.splice(h,1)
-}};
-a.util={browser:{},parseHeaders:function(i){var h,k=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,j={};
-while(h=k.exec(i)){j[h[1]]=h[2]
-}return j
-},now:function(){return new Date().getTime()
-},isArray:function(h){return Object.prototype.toString.call(h)==="[object Array]"
-},inArray:function(k,l){if(!Array.prototype.indexOf){var h=l.length;
-for(var j=0;
-j<h;
-++j){if(l[j]===k){return j
-}}return -1
-}return l.indexOf(k)
-},isBinary:function(h){return/^\[object\s(?:Blob|ArrayBuffer|.+Array)\]$/.test(Object.prototype.toString.call(h))
-},isFunction:function(h){return Object.prototype.toString.call(h)==="[object Function]"
-},getAbsoluteURL:function(h){var i=document.createElement("div");
-i.innerHTML='<a href="'+h+'"/>';
-return encodeURI(decodeURI(i.firstChild.href))
-},prepareURL:function(i){var j=a.util.now();
-var h=i.replace(/([?&])_=[^&]*/,"$1_="+j);
-return h+(h===i?(/\?/.test(i)?"&":"?")+"_="+j:"")
-},trim:function(h){if(!String.prototype.trim){return h.toString().replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,"").replace(/\s+/g," ")
-}else{return h.toString().trim()
-}},param:function(l){var j,h=[];
-function k(m,n){n=a.util.isFunction(n)?n():(n==null?"":n);
-h.push(encodeURIComponent(m)+"="+encodeURIComponent(n))
-}function i(n,o){var m;
-if(a.util.isArray(o)){a.util.each(o,function(q,p){if(/\[\]$/.test(n)){k(n,p)
-}else{i(n+"["+(typeof p==="object"?q:"")+"]",p)
-}})
-}else{if(Object.prototype.toString.call(o)==="[object Object]"){for(m in o){i(n+"["+m+"]",o[m])
-}}else{k(n,o)
-}}}for(j in l){i(j,l[j])
-}return h.join("&").replace(/%20/g,"+")
-},storage:function(){try{return !!(window.localStorage&&window.StorageEvent)
-}catch(h){return false
-}},iterate:function(j,i){var k;
-i=i||0;
-(function h(){k=setTimeout(function(){if(j()===false){return
-}h()
-},i)
-})();
-return function(){clearTimeout(k)
-}
-},each:function(n,o,j){if(!n){return
-}var m,k=0,l=n.length,h=a.util.isArray(n);
-if(j){if(h){for(;
-k<l;
-k++){m=o.apply(n[k],j);
-if(m===false){break
-}}}else{for(k in n){m=o.apply(n[k],j);
-if(m===false){break
-}}}}else{if(h){for(;
-k<l;
-k++){m=o.call(n[k],k,n[k]);
-if(m===false){break
-}}}else{for(k in n){m=o.call(n[k],k,n[k]);
-if(m===false){break
-}}}}return n
-},extend:function(l){var k,j,h;
-for(k=1;
-k<arguments.length;
-k++){if((j=arguments[k])!=null){for(h in j){l[h]=j[h]
-}}}return l
-},on:function(j,i,h){if(j.addEventListener){j.addEventListener(i,h,false)
-}else{if(j.attachEvent){j.attachEvent("on"+i,h)
-}}},off:function(j,i,h){if(j.removeEventListener){j.removeEventListener(i,h,false)
-}else{if(j.detachEvent){j.detachEvent("on"+i,h)
-}}},log:function(j,i){if(window.console){var h=window.console[j];
-if(typeof h==="function"){h.apply(window.console,i)
-}}},warn:function(){a.util.log("warn",arguments)
-},info:function(){a.util.log("info",arguments)
-},debug:function(){a.util.log("debug",arguments)
-},error:function(){a.util.log("error",arguments)
-},xhr:function(){try{return new window.XMLHttpRequest()
-}catch(i){try{return new window.ActiveXObject("Microsoft.XMLHTTP")
-}catch(h){}}},parseJSON:function(h){return !h?null:window.JSON&&window.JSON.parse?window.JSON.parse(h):new Function("return "+h)()
-},stringifyJSON:function(j){var m=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,k={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};
-function h(n){return'"'+n.replace(m,function(o){var p=k[o];
-return typeof p==="string"?p:"\\u"+("0000"+o.charCodeAt(0).toString(16)).slice(-4)
-})+'"'
-}function i(o){return o<10?"0"+o:o
-}return window.JSON&&window.JSON.stringify?window.JSON.stringify(j):(function l(s,r){var q,p,n,o,u=r[s],t=typeof u;
-if(u&&typeof u==="object"&&typeof u.toJSON==="function"){u=u.toJSON(s);
-t=typeof u
-}switch(t){case"string":return h(u);
-case"number":return isFinite(u)?String(u):"null";
-case"boolean":return String(u);
-case"object":if(!u){return"null"
-}switch(Object.prototype.toString.call(u)){case"[object Date]":return isFinite(u.valueOf())?'"'+u.getUTCFullYear()+"-"+i(u.getUTCMonth()+1)+"-"+i(u.getUTCDate())+"T"+i(u.getUTCHours())+":"+i(u.getUTCMinutes())+":"+i(u.getUTCSeconds())+'Z"':"null";
-case"[object Array]":n=u.length;
-o=[];
-for(q=0;
-q<n;
-q++){o.push(l(q,u)||"null")
-}return"["+o.join(",")+"]";
-default:o=[];
-for(q in u){if(b.call(u,q)){p=l(q,u);
-if(p){o.push(h(q)+":"+p)
-}}}return"{"+o.join(",")+"}"
-}}})("",{"":j})
-},checkCORSSupport:function(){if(a.util.browser.msie&&!window.XDomainRequest&&+a.util.browser.version.split(".")[0]<11){return true
-}else{if(a.util.browser.opera&&+a.util.browser.version.split(".")<12){return true
-}else{if(a.util.trim(navigator.userAgent).slice(0,16)==="KreaTVWebKit/531"){return true
-}else{if(a.util.trim(navigator.userAgent).slice(-7).toLowerCase()==="kreatel"){return true
-}}}}var h=navigator.userAgent.toLowerCase();
-var i=h.indexOf("android")>-1;
-if(i){return true
-}return false
-}};
-d=a.util.now();
-(function(){var i=navigator.userAgent.toLowerCase(),h=/(chrome)[ \/]([\w.]+)/.exec(i)||/(webkit)[ \/]([\w.]+)/.exec(i)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(i)||/(msie) ([\w.]+)/.exec(i)||/(trident)(?:.*? rv:([\w.]+)|)/.exec(i)||i.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(i)||[];
-a.util.browser[h[1]||""]=true;
-a.util.browser.version=h[2]||"0";
-if(a.util.browser.trident){a.util.browser.msie=true
-}if(a.util.browser.msie||(a.util.browser.mozilla&&+a.util.browser.version.split(".")[0]===1)){a.util.storage=false
-}})();
-a.util.on(window,"unload",function(h){a.unsubscribe()
-});
-a.util.on(window,"keypress",function(h){if(h.charCode===27||h.keyCode===27){if(h.preventDefault){h.preventDefault()
-}}});
-a.util.on(window,"offline",function(){a.unsubscribe()
-});
-return a
-}));
\ No newline at end of file
diff --git a/wave/dependencies/compile/runtime/javascript-2.1.5/javascript/atmosphere.js b/wave/dependencies/compile/runtime/javascript-2.1.5/javascript/atmosphere.js
deleted file mode 100644
index d8b0317..0000000
--- a/wave/dependencies/compile/runtime/javascript-2.1.5/javascript/atmosphere.js
+++ /dev/null
@@ -1,3081 +0,0 @@
-/*
- * Copyright 2014 Jeanfrancois Arcand
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * Atmosphere.js
- * https://github.com/Atmosphere/atmosphere-javascript
- * 
- * API reference
- * https://github.com/Atmosphere/atmosphere/wiki/jQuery.atmosphere.js-API
- * 
- * Highly inspired by 
- * - Portal by Donghwan Kim http://flowersinthesand.github.io/portal/
- */
-(function(root, factory) {
-    if (typeof define === "function" && define.amd) {
-        // AMD
-        define(factory);
-    } else {
-        // Browser globals, Window
-        root.atmosphere = factory();
-    }
-}(this, function() {
-
-    "use strict";
-
-    var version = "2.1.5-javascript",
-        atmosphere = {},
-        guid,
-        requests = [],
-        callbacks = [],
-        uuid = 0,
-        hasOwn = Object.prototype.hasOwnProperty;
-
-    atmosphere = {
-
-        onError: function (response) {
-        },
-        onClose: function (response) {
-        },
-        onOpen: function (response) {
-        },
-        onReopen: function (response) {
-        },
-        onMessage: function (response) {
-        },
-        onReconnect: function (request, response) {
-        },
-        onMessagePublished: function (response) {
-        },
-        onTransportFailure: function (errorMessage, _request) {
-        },
-        onLocalMessage: function (response) {
-        },
-        onFailureToReconnect: function (request, response) {
-        },
-        onClientTimeout: function(request){
-        },
-
-        AtmosphereRequest: function (options) {
-
-            /**
-             * {Object} Request parameters.
-             *
-             * @private
-             */
-            var _request = {
-                timeout: 300000,
-                method: 'GET',
-                headers: {},
-                contentType: '',
-                callback: null,
-                url: '',
-                data: '',
-                suspend: true,
-                maxRequest: -1,
-                reconnect: true,
-                maxStreamingLength: 10000000,
-                lastIndex: 0,
-                logLevel: 'info',
-                requestCount: 0,
-                fallbackMethod: 'GET',
-                fallbackTransport: 'streaming',
-                transport: 'long-polling',
-                webSocketImpl: null,
-                webSocketBinaryType: null,
-                dispatchUrl: null,
-                webSocketPathDelimiter: "@@",
-                enableXDR: false,
-                rewriteURL: false,
-                attachHeadersAsQueryString: true,
-                executeCallbackBeforeReconnect: false,
-                readyState: 0,
-                lastTimestamp: 0,
-                withCredentials: false,
-                trackMessageLength: false,
-                messageDelimiter: '|',
-                connectTimeout: -1,
-                reconnectInterval: 0,
-                dropHeaders: true,
-                uuid: 0,
-                async: true,
-                shared: false,
-                readResponsesHeaders: false,
-                maxReconnectOnClose: 5,
-                enableProtocol: true,
-                pollingInterval : 0,
-                onError: function (response) {
-                },
-                onClose: function (response) {
-                },
-                onOpen: function (response) {
-                },
-                onMessage: function (response) {
-                },
-                onReopen: function (request, response) {
-                },
-                onReconnect: function (request, response) {
-                },
-                onMessagePublished: function (response) {
-                },
-                onTransportFailure: function (reason, request) {
-                },
-                onLocalMessage: function (request) {
-                },
-                onFailureToReconnect: function (request, response) {
-                },
-                onClientTimeout: function(request){
-                }
-            };
-
-            /**
-             * {Object} Request's last response.
-             *
-             * @private
-             */
-            var _response = {
-                status: 200,
-                reasonPhrase: "OK",
-                responseBody: '',
-                messages: [],
-                headers: [],
-                state: "messageReceived",
-                transport: "polling",
-                error: null,
-                request: null,
-                partialMessage: "",
-                errorHandled: false,
-                closedByClientTimeout: false
-            };
-
-            /**
-             * {websocket} Opened web socket.
-             *
-             * @private
-             */
-            var _websocket = null;
-
-            /**
-             * {SSE} Opened SSE.
-             *
-             * @private
-             */
-            var _sse = null;
-
-            /**
-             * {XMLHttpRequest, ActiveXObject} Opened ajax request (in case of http-streaming or long-polling)
-             *
-             * @private
-             */
-            var _activeRequest = null;
-
-            /**
-             * {Object} Object use for streaming with IE.
-             *
-             * @private
-             */
-            var _ieStream = null;
-
-            /**
-             * {Object} Object use for jsonp transport.
-             *
-             * @private
-             */
-            var _jqxhr = null;
-
-            /**
-             * {boolean} If request has been subscribed or not.
-             *
-             * @private
-             */
-            var _subscribed = true;
-
-            /**
-             * {number} Number of test reconnection.
-             *
-             * @private
-             */
-            var _requestCount = 0;
-
-            /**
-             * {boolean} If request is currently aborded.
-             *
-             * @private
-             */
-            var _abordingConnection = false;
-
-            /**
-             * A local "channel' of communication.
-             *
-             * @private
-             */
-            var _localSocketF = null;
-
-            /**
-             * The storage used.
-             *
-             * @private
-             */
-            var _storageService;
-
-            /**
-             * Local communication
-             *
-             * @private
-             */
-            var _localStorageService = null;
-
-            /**
-             * A Unique ID
-             *
-             * @private
-             */
-            var guid = atmosphere.util.now();
-
-            /** Trace time */
-            var _traceTimer;
-
-            /** Key for connection sharing */
-            var _sharingKey;
-
-            // Automatic call to subscribe
-            _subscribe(options);
-
-            /**
-             * Initialize atmosphere request object.
-             *
-             * @private
-             */
-            function _init() {
-                _subscribed = true;
-                _abordingConnection = false;
-                _requestCount = 0;
-
-                _websocket = null;
-                _sse = null;
-                _activeRequest = null;
-                _ieStream = null;
-            }
-
-            /**
-             * Re-initialize atmosphere object.
-             *
-             * @private
-             */
-            function _reinit() {
-                _clearState();
-                _init();
-            }
-
-            /**
-             *
-             * @private
-             */
-            function _verifyStreamingLength(ajaxRequest, rq) {
-                // Wait to be sure we have the full message before closing.
-                if (_response.partialMessage === "" && (rq.transport === 'streaming') && (ajaxRequest.responseText.length > rq.maxStreamingLength)) {
-                    _response.messages = [];
-                    rq.reconnectingOnLength = true;
-                    rq.isReopen = true;
-                    _invokeClose(true);
-                    _disconnect();
-                    _clearState();
-                    _reconnect(ajaxRequest, rq, rq.pollingInterval);
-                }
-            }
-
-            /**
-             * Disconnect
-             *
-             * @private
-             */
-            function _disconnect() {
-                if (_request.enableProtocol && !_request.firstMessage) {
-                    var query = "X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=" + _request.uuid;
-
-                    atmosphere.util.each(_request.headers, function (name, value) {
-                        var h = atmosphere.util.isFunction(value) ? value.call(this, _request, _request, _response) : value;
-                        if (h != null) {
-                            query += "&" + encodeURIComponent(name) + "=" + encodeURIComponent(h);
-                        }
-                    });
-
-                    var url = _request.url.replace(/([?&])_=[^&]*/, query);
-                    url = url + (url === _request.url ? (/\?/.test(_request.url) ? "&" : "?") + query : "");
-
-                    var rq = {
-                        connected: false
-                    };
-                    var closeR = new atmosphere.AtmosphereRequest(rq);
-                    closeR.attachHeadersAsQueryString = false;
-                    closeR.dropHeaders = true;
-                    closeR.url = url;
-                    closeR.contentType = "text/plain";
-                    closeR.transport = 'polling';
-                    closeR.method = 'GET';
-                    closeR.data = '';
-                    closeR.async = false;
-                    _pushOnClose("", closeR);
-                }
-            }
-
-            /**
-             * Close request.
-             *
-             * @private
-             */
-            function _close() {
-                if (_request.reconnectId) {
-                    clearTimeout(_request.reconnectId);
-                    delete _request.reconnectId;
-                }
-                _request.reconnect = false;
-                _abordingConnection = true;
-                _response.request = _request;
-                _response.state = 'unsubscribe';
-                _response.responseBody = "";
-                _response.status = 408;
-                _response.partialMessage = "";
-                _invokeCallback();
-                _disconnect();
-                _clearState();
-            }
-
-            function _clearState() {
-                _response.partialMessage = "";
-                if (_request.id) {
-                    clearTimeout(_request.id);
-                }
-
-                if (_ieStream != null) {
-                    _ieStream.close();
-                    _ieStream = null;
-                }
-                if (_jqxhr != null) {
-                    _jqxhr.abort();
-                    _jqxhr = null;
-                }
-                if (_activeRequest != null) {
-                    _activeRequest.abort();
-                    _activeRequest = null;
-                }
-                if (_websocket != null) {
-                    if (_websocket.canSendMessage) {
-                        _websocket.close();
-                    }
-                    _websocket = null;
-                }
-                if (_sse != null) {
-                    _sse.close();
-                    _sse = null;
-                }
-                _clearStorage();
-            }
-
-            function _clearStorage() {
-                // Stop sharing a connection
-                if (_storageService != null) {
-                    // Clears trace timer
-                    clearInterval(_traceTimer);
-                    // Removes the trace
-                    document.cookie = _sharingKey + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
-                    // The heir is the parent unless unloading
-                    _storageService.signal("close", {
-                        reason: "",
-                        heir: !_abordingConnection ? guid : (_storageService.get("children") || [])[0]
-                    });
-                    _storageService.close();
-                }
-                if (_localStorageService != null) {
-                    _localStorageService.close();
-                }
-            }
-
-            /**
-             * Subscribe request using request transport. <br>
-             * If request is currently opened, this one will be closed.
-             *
-             * @param {Object} Request parameters.
-             * @private
-             */
-            function _subscribe(options) {
-                _reinit();
-
-                _request = atmosphere.util.extend(_request, options);
-                // Allow at least 1 request
-                _request.mrequest = _request.reconnect;
-                if (!_request.reconnect) {
-                    _request.reconnect = true;
-                }
-            }
-
-            /**
-             * Check if web socket is supported (check for custom implementation provided by request object or browser implementation).
-             *
-             * @returns {boolean} True if web socket is supported, false otherwise.
-             * @private
-             */
-            function _supportWebsocket() {
-                return _request.webSocketImpl != null || window.WebSocket || window.MozWebSocket;
-            }
-
-            /**
-             * Check if server side events (SSE) is supported (check for custom implementation provided by request object or browser implementation).
-             *
-             * @returns {boolean} True if web socket is supported, false otherwise.
-             * @private
-             */
-            function _supportSSE() {
-                return window.EventSource;
-            }
-
-            /**
-             * Open request using request transport. <br>
-             * If request transport is 'websocket' but websocket can't be opened, request will automatically reconnect using fallback transport.
-             *
-             * @private
-             */
-            function _execute() {
-                // Shared across multiple tabs/windows.
-                if (_request.shared) {
-                    _localStorageService = _local(_request);
-                    if (_localStorageService != null) {
-                        if (_request.logLevel === 'debug') {
-                            atmosphere.util.debug("Storage service available. All communication will be local");
-                        }
-
-                        if (_localStorageService.open(_request)) {
-                            // Local connection.
-                            return;
-                        }
-                    }
-
-                    if (_request.logLevel === 'debug') {
-                        atmosphere.util.debug("No Storage service available.");
-                    }
-                    // Wasn't local or an error occurred
-                    _localStorageService = null;
-                }
-
-                // Protocol
-                _request.firstMessage = uuid == 0 ? true : false;
-                _request.isOpen = false;
-                _request.ctime = atmosphere.util.now();
-
-                // We carry any UUID set by the user or from a previous connection.
-                if (_request.uuid === 0) {
-                    _request.uuid = uuid;
-                }
-                _response.closedByClientTimeout = false;
-
-                if (_request.transport !== 'websocket' && _request.transport !== 'sse') {
-                    _executeRequest(_request);
-
-                } else if (_request.transport === 'websocket') {
-                    if (!_supportWebsocket()) {
-                        _reconnectWithFallbackTransport("Websocket is not supported, using request.fallbackTransport (" + _request.fallbackTransport
-                            + ")");
-                    } else {
-                        _executeWebSocket(false);
-                    }
-                } else if (_request.transport === 'sse') {
-                    if (!_supportSSE()) {
-                        _reconnectWithFallbackTransport("Server Side Events(SSE) is not supported, using request.fallbackTransport ("
-                            + _request.fallbackTransport + ")");
-                    } else {
-                        _executeSSE(false);
-                    }
-                }
-            }
-
-            function _local(request) {
-                var trace, connector, orphan, name = "atmosphere-" + request.url, connectors = {
-                    storage: function () {
-                        function onstorage(event) {
-                            if (event.key === name && event.newValue) {
-                                listener(event.newValue);
-                            }
-                        }
-
-                        if (!atmosphere.util.storage) {
-                            return;
-                        }
-
-                        var storage = window.localStorage,
-                            get = function (key) {
-                                return atmosphere.util.parseJSON(storage.getItem(name + "-" + key));
-                            },
-                            set = function (key, value) {
-                                storage.setItem(name + "-" + key, atmosphere.util.stringifyJSON(value));
-                            };
-
-                        return {
-                            init: function () {
-                                set("children", get("children").concat([guid]));
-                                atmosphere.util.on(window, "storage", onstorage);
-                                return get("opened");
-                            },
-                            signal: function (type, data) {
-                                storage.setItem(name, atmosphere.util.stringifyJSON({
-                                    target: "p",
-                                    type: type,
-                                    data: data
-                                }));
-                            },
-                            close: function () {
-                                var children = get("children");
-
-                                atmosphere.util.off(window, "storage", onstorage);
-                                if (children) {
-                                    if (removeFromArray(children, request.id)) {
-                                        set("children", children);
-                                    }
-                                }
-                            }
-                        };
-                    },
-                    windowref: function () {
-                        var win = window.open("", name.replace(/\W/g, ""));
-
-                        if (!win || win.closed || !win.callbacks) {
-                            return;
-                        }
-
-                        return {
-                            init: function () {
-                                win.callbacks.push(listener);
-                                win.children.push(guid);
-                                return win.opened;
-                            },
-                            signal: function (type, data) {
-                                if (!win.closed && win.fire) {
-                                    win.fire(atmosphere.util.stringifyJSON({
-                                        target: "p",
-                                        type: type,
-                                        data: data
-                                    }));
-                                }
-                            },
-                            close: function () {
-                                // Removes traces only if the parent is alive
-                                if (!orphan) {
-                                    removeFromArray(win.callbacks, listener);
-                                    removeFromArray(win.children, guid);
-                                }
-                            }
-
-                        };
-                    }
-                };
-
-                function removeFromArray(array, val) {
-                    var i, length = array.length;
-
-                    for (i = 0; i < length; i++) {
-                        if (array[i] === val) {
-                            array.splice(i, 1);
-                        }
-                    }
-
-                    return length !== array.length;
-                }
-
-                // Receives open, close and message command from the parent
-                function listener(string) {
-                    var command = atmosphere.util.parseJSON(string), data = command.data;
-
-                    if (command.target === "c") {
-                        switch (command.type) {
-                            case "open":
-                                _open("opening", 'local', _request);
-                                break;
-                            case "close":
-                                if (!orphan) {
-                                    orphan = true;
-                                    if (data.reason === "aborted") {
-                                        _close();
-                                    } else {
-                                        // Gives the heir some time to reconnect
-                                        if (data.heir === guid) {
-                                            _execute();
-                                        } else {
-                                            setTimeout(function () {
-                                                _execute();
-                                            }, 100);
-                                        }
-                                    }
-                                }
-                                break;
-                            case "message":
-                                _prepareCallback(data, "messageReceived", 200, request.transport);
-                                break;
-                            case "localMessage":
-                                _localMessage(data);
-                                break;
-                        }
-                    }
-                }
-
-                function findTrace() {
-                    var matcher = new RegExp("(?:^|; )(" + encodeURIComponent(name) + ")=([^;]*)").exec(document.cookie);
-                    if (matcher) {
-                        return atmosphere.util.parseJSON(decodeURIComponent(matcher[2]));
-                    }
-                }
-
-                // Finds and validates the parent socket's trace from the cookie
-                trace = findTrace();
-                if (!trace || atmosphere.util.now() - trace.ts > 1000) {
-                    return;
-                }
-
-                // Chooses a connector
-                connector = connectors.storage() || connectors.windowref();
-                if (!connector) {
-                    return;
-                }
-
-                return {
-                    open: function () {
-                        var parentOpened;
-
-                        // Checks the shared one is alive
-                        _traceTimer = setInterval(function () {
-                            var oldTrace = trace;
-                            trace = findTrace();
-                            if (!trace || oldTrace.ts === trace.ts) {
-                                // Simulates a close signal
-                                listener(atmosphere.util.stringifyJSON({
-                                    target: "c",
-                                    type: "close",
-                                    data: {
-                                        reason: "error",
-                                        heir: oldTrace.heir
-                                    }
-                                }));
-                            }
-                        }, 1000);
-
-                        parentOpened = connector.init();
-                        if (parentOpened) {
-                            // Firing the open event without delay robs the user of the opportunity to bind connecting event handlers
-                            setTimeout(function () {
-                                _open("opening", 'local', request);
-                            }, 50);
-                        }
-                        return parentOpened;
-                    },
-                    send: function (event) {
-                        connector.signal("send", event);
-                    },
-                    localSend: function (event) {
-                        connector.signal("localSend", atmosphere.util.stringifyJSON({
-                            id: guid,
-                            event: event
-                        }));
-                    },
-                    close: function () {
-                        // Do not signal the parent if this method is executed by the unload event handler
-                        if (!_abordingConnection) {
-                            clearInterval(_traceTimer);
-                            connector.signal("close");
-                            connector.close();
-                        }
-                    }
-                };
-            }
-
-            function share() {
-                var storageService, name = "atmosphere-" + _request.url, servers = {
-                    // Powered by the storage event and the localStorage
-                    // http://www.w3.org/TR/webstorage/#event-storage
-                    storage: function () {
-                        function onstorage(event) {
-                            // When a deletion, newValue initialized to null
-                            if (event.key === name && event.newValue) {
-                                listener(event.newValue);
-                            }
-                        }
-
-                        if (!atmosphere.util.storage) {
-                            return;
-                        }
-
-                        var storage = window.localStorage;
-
-                        return {
-                            init: function () {
-                                // Handles the storage event
-                                atmosphere.util.on(window, "storage", onstorage);
-                            },
-                            signal: function (type, data) {
-                                storage.setItem(name, atmosphere.util.stringifyJSON({
-                                    target: "c",
-                                    type: type,
-                                    data: data
-                                }));
-                            },
-                            get: function (key) {
-                                return atmosphere.util.parseJSON(storage.getItem(name + "-" + key));
-                            },
-                            set: function (key, value) {
-                                storage.setItem(name + "-" + key, atmosphere.util.stringifyJSON(value));
-                            },
-                            close: function () {
-                                atmosphere.util.off(window, "storage", onstorage);
-                                storage.removeItem(name);
-                                storage.removeItem(name + "-opened");
-                                storage.removeItem(name + "-children");
-                            }
-
-                        };
-                    },
-                    // Powered by the window.open method
-                    // https://developer.mozilla.org/en/DOM/window.open
-                    windowref: function () {
-                        // Internet Explorer raises an invalid argument error
-                        // when calling the window.open method with the name containing non-word characters
-                        var neim = name.replace(/\W/g, ""), container = document.getElementById(neim), win;
-
-                        if (!container) {
-                            container = document.createElement("div");
-                            container.id = neim;
-                            container.style.display = "none";
-                            container.innerHTML = '<iframe name="' + neim + '" />';
-                            document.body.appendChild(container);
-                        }
-
-                        win = container.firstChild.contentWindow;
-
-                        return {
-                            init: function () {
-                                // Callbacks from different windows
-                                win.callbacks = [listener];
-                                // In IE 8 and less, only string argument can be safely passed to the function in other window
-                                win.fire = function (string) {
-                                    var i;
-
-                                    for (i = 0; i < win.callbacks.length; i++) {
-                                        win.callbacks[i](string);
-                                    }
-                                };
-                            },
-                            signal: function (type, data) {
-                                if (!win.closed && win.fire) {
-                                    win.fire(atmosphere.util.stringifyJSON({
-                                        target: "c",
-                                        type: type,
-                                        data: data
-                                    }));
-                                }
-                            },
-                            get: function (key) {
-                                return !win.closed ? win[key] : null;
-                            },
-                            set: function (key, value) {
-                                if (!win.closed) {
-                                    win[key] = value;
-                                }
-                            },
-                            close: function () {
-                            }
-                        };
-                    }
-                };
-
-                // Receives send and close command from the children
-                function listener(string) {
-                    var command = atmosphere.util.parseJSON(string), data = command.data;
-
-                    if (command.target === "p") {
-                        switch (command.type) {
-                            case "send":
-                                _push(data);
-                                break;
-                            case "localSend":
-                                _localMessage(data);
-                                break;
-                            case "close":
-                                _close();
-                                break;
-                        }
-                    }
-                }
-
-                _localSocketF = function propagateMessageEvent(context) {
-                    storageService.signal("message", context);
-                };
-
-                function leaveTrace() {
-                    document.cookie = _sharingKey + "=" +
-                        // Opera's JSON implementation ignores a number whose a last digit of 0 strangely
-                        // but has no problem with a number whose a last digit of 9 + 1
-                        encodeURIComponent(atmosphere.util.stringifyJSON({
-                            ts: atmosphere.util.now() + 1,
-                            heir: (storageService.get("children") || [])[0]
-                        })) + "; path=/";
-                }
-
-                // Chooses a storageService
-                storageService = servers.storage() || servers.windowref();
-                storageService.init();
-
-                if (_request.logLevel === 'debug') {
-                    atmosphere.util.debug("Installed StorageService " + storageService);
-                }
-
-                // List of children sockets
-                storageService.set("children", []);
-
-                if (storageService.get("opened") != null && !storageService.get("opened")) {
-                    // Flag indicating the parent socket is opened
-                    storageService.set("opened", false);
-                }
-                // Leaves traces
-                _sharingKey = encodeURIComponent(name);
-                leaveTrace();
-                _traceTimer = setInterval(leaveTrace, 1000);
-
-                _storageService = storageService;
-            }
-
-            /**
-             * @private
-             */
-            function _open(state, transport, request) {
-                if (_request.shared && transport !== 'local') {
-                    share();
-                }
-
-                if (_storageService != null) {
-                    _storageService.set("opened", true);
-                }
-
-                request.close = function () {
-                    _close();
-                };
-
-                if (_requestCount > 0 && state === 're-connecting') {
-                    request.isReopen = true;
-                    _tryingToReconnect(_response);
-                } else if (_response.error == null) {
-                    _response.request = request;
-                    var prevState = _response.state;
-                    _response.state = state;
-                    var prevTransport = _response.transport;
-                    _response.transport = transport;
-
-                    var _body = _response.responseBody;
-                    _invokeCallback();
-                    _response.responseBody = _body;
-
-                    _response.state = prevState;
-                    _response.transport = prevTransport;
-                }
-            }
-
-            /**
-             * Execute request using jsonp transport.
-             *
-             * @param request {Object} request Request parameters, if undefined _request object will be used.
-             * @private
-             */
-            function _jsonp(request) {
-                // When CORS is enabled, make sure we force the proper transport.
-                request.transport = "jsonp";
-
-                var rq = _request, script;
-                if ((request != null) && (typeof (request) !== 'undefined')) {
-                    rq = request;
-                }
-
-                _jqxhr = {
-                    open: function () {
-                        var callback = "atmosphere" + (++guid);
-
-                        function poll() {
-                            var url = rq.url;
-                            if (rq.dispatchUrl != null) {
-                                url += rq.dispatchUrl;
-                            }
-
-                            var data = rq.data;
-                            if (rq.attachHeadersAsQueryString) {
-                                url = _attachHeaders(rq);
-                                if (data !== '') {
-                                    url += "&X-Atmosphere-Post-Body=" + encodeURIComponent(data);
-                                }
-                                data = '';
-                            }
-
-                            var head = document.head || document.getElementsByTagName("head")[0] || document.documentElement;
-
-                            script = document.createElement("script");
-                            script.src = url + "&jsonpTransport=" + callback;
-                            script.clean = function () {
-                                script.clean = script.onerror = script.onload = script.onreadystatechange = null;
-                                if (script.parentNode) {
-                                    script.parentNode.removeChild(script);
-                                }
-                            };
-                            script.onload = script.onreadystatechange = function () {
-                                if (!script.readyState || /loaded|complete/.test(script.readyState)) {
-                                    script.clean();
-                                }
-                            };
-                            script.onerror = function () {
-                                script.clean();
-                                rq.lastIndex = 0;
-
-                                if (rq.openId) {
-                                    clearTimeout(rq.openId);
-                                }
-
-                                if (rq.reconnect && _requestCount++ < rq.maxReconnectOnClose) {
-                                    _open('re-connecting', rq.transport, rq);
-                                    _reconnect(_jqxhr, rq, request.reconnectInterval);
-                                    rq.openId = setTimeout(function() {
-                                        _triggerOpen(rq);
-                                    }, rq.reconnectInterval + 1000);
-                                } else {
-                                    _onError(0, "maxReconnectOnClose reached");
-                                }
-                            };
-
-                            head.insertBefore(script, head.firstChild);
-                        }
-
-                        // Attaches callback
-                        window[callback] = function (msg) {
-                            if (rq.reconnect) {
-                                if (rq.maxRequest === -1 || rq.requestCount++ < rq.maxRequest) {
-                                    // _readHeaders(_jqxhr, rq);
-
-                                    if (!rq.executeCallbackBeforeReconnect) {
-                                        _reconnect(_jqxhr, rq, rq.pollingInterval);
-                                    }
-
-                                    if (msg != null && typeof msg !== 'string') {
-                                        try {
-                                            msg = msg.message;
-                                        } catch (err) {
-                                            // The message was partial
-                                        }
-                                    }
-
-                                    var skipCallbackInvocation = _trackMessageSize(msg, rq, _response);
-                                    if (!skipCallbackInvocation) {
-                                        _prepareCallback(_response.responseBody, "messageReceived", 200, rq.transport);
-                                    }
-
-                                    if (rq.executeCallbackBeforeReconnect) {
-                                        _reconnect(_jqxhr, rq, rq.pollingInterval);
-                                    }
-                                } else {
-                                    atmosphere.util.log(_request.logLevel, ["JSONP reconnect maximum try reached " + _request.requestCount]);
-                                    _onError(0, "maxRequest reached");
-                                }
-                            }
-                        };
-                        setTimeout(function () {
-                            poll();
-                        }, 50);
-                    },
-                    abort: function () {
-                        if (script && script.clean) {
-                            script.clean();
-                        }
-                    }
-                };
-
-                _jqxhr.open();
-            }
-
-            /**
-             * Build websocket object.
-             *
-             * @param location {string} Web socket url.
-             * @returns {websocket} Web socket object.
-             * @private
-             */
-            function _getWebSocket(location) {
-                if (_request.webSocketImpl != null) {
-                    return _request.webSocketImpl;
-                } else {
-                    if (window.WebSocket) {
-                        return new WebSocket(location);
-                    } else {
-                        return new MozWebSocket(location);
-                    }
-                }
-            }
-
-            /**
-             * Build web socket url from request url.
-             *
-             * @return {string} Web socket url (start with "ws" or "wss" for secure web socket).
-             * @private
-             */
-            function _buildWebSocketUrl() {
-                return _attachHeaders(_request, atmosphere.util.getAbsoluteURL(_request.url)).replace(/^http/, "ws");
-            }
-
-            /**
-             * Build SSE url from request url.
-             *
-             * @return a url with Atmosphere's headers
-             * @private
-             */
-            function _buildSSEUrl() {
-                var url = _attachHeaders(_request);
-                return url;
-            }
-
-            /**
-             * Open SSE. <br>
-             * Automatically use fallback transport if SSE can't be opened.
-             *
-             * @private
-             */
-            function _executeSSE(sseOpened) {
-
-                _response.transport = "sse";
-
-                var location = _buildSSEUrl();
-
-                if (_request.logLevel === 'debug') {
-                    atmosphere.util.debug("Invoking executeSSE");
-                    atmosphere.util.debug("Using URL: " + location);
-                }
-
-                if (_request.enableProtocol && sseOpened) {
-                    var time = atmosphere.util.now() - _request.ctime;
-                    _request.lastTimestamp = Number(_request.stime) + Number(time);
-                }
-
-                if (sseOpened && !_request.reconnect) {
-                    if (_sse != null) {
-                        _clearState();
-                    }
-                    return;
-                }
-
-                try {
-                    _sse = new EventSource(location, {
-                        withCredentials: _request.withCredentials
-                    });
-                } catch (e) {
-                    _onError(0, e);
-                    _reconnectWithFallbackTransport("SSE failed. Downgrading to fallback transport and resending");
-                    return;
-                }
-
-                if (_request.connectTimeout > 0) {
-                    _request.id = setTimeout(function () {
-                        if (!sseOpened) {
-                            _clearState();
-                        }
-                    }, _request.connectTimeout);
-                }
-
-                _sse.onopen = function (event) {
-                    _timeout(_request);
-                    if (_request.logLevel === 'debug') {
-                        atmosphere.util.debug("SSE successfully opened");
-                    }
-
-                    if (!_request.enableProtocol) {
-                        if (!sseOpened) {
-                            _open('opening', "sse", _request);
-                        } else {
-                            _open('re-opening', "sse", _request);
-                        }
-                    } else if (_request.isReopen) {
-                        _request.isReopen = false;
-                        _open('re-opening', _request.transport, _request);
-                    }
-
-                    sseOpened = true;
-
-                    if (_request.method === 'POST') {
-                        _response.state = "messageReceived";
-                        _sse.send(_request.data);
-                    }
-                };
-
-                _sse.onmessage = function (message) {
-                    _timeout(_request);
-
-                    if (!_request.enableXDR && message.origin && message.origin !== window.location.protocol + "//" + window.location.host) {
-                        atmosphere.util.log(_request.logLevel, ["Origin was not " + window.location.protocol + "//" + window.location.host]);
-                        return;
-                    }
-
-                    _response.state = 'messageReceived';
-                    _response.status = 200;
-
-                    message = message.data;
-                    var skipCallbackInvocation = _trackMessageSize(message, _request, _response);
-
-                    // https://github.com/remy/polyfills/blob/master/EventSource.js
-                    // Since we polling.
-                   /* if (_sse.URL) {
-                        _sse.interval = 100;
-                        _sse.URL = _buildSSEUrl();
-                    } */
-
-                    if (!skipCallbackInvocation) {
-                        _invokeCallback();
-                        _response.responseBody = '';
-                        _response.messages = [];
-                    }
-                };
-
-                _sse.onerror = function (message) {
-                    clearTimeout(_request.id);
-
-                    if (_response.closedByClientTimeout) return;
-
-                    _invokeClose(sseOpened);
-                    _clearState();
-
-                    if (_abordingConnection) {
-                        atmosphere.util.log(_request.logLevel, ["SSE closed normally"]);
-                    } else if (!sseOpened) {
-                        _reconnectWithFallbackTransport("SSE failed. Downgrading to fallback transport and resending");
-                    } else if (_request.reconnect && (_response.transport === 'sse')) {
-                        if (_requestCount++ < _request.maxReconnectOnClose) {
-                            _open('re-connecting', _request.transport, _request);
-                            if (_request.reconnectInterval > 0) {
-                                _request.reconnectId = setTimeout(function () {
-                                    _executeSSE(true);
-                                }, _request.reconnectInterval);
-                            } else {
-                                _executeSSE(true);
-                            }
-                            _response.responseBody = "";
-                            _response.messages = [];
-                        } else {
-                            atmosphere.util.log(_request.logLevel, ["SSE reconnect maximum try reached " + _requestCount]);
-                            _onError(0, "maxReconnectOnClose reached");
-                        }
-                    }
-                };
-            }
-
-            /**
-             * Open web socket. <br>
-             * Automatically use fallback transport if web socket can't be opened.
-             *
-             * @private
-             */
-            function _executeWebSocket(webSocketOpened) {
-
-                _response.transport = "websocket";
-
-                if (_request.enableProtocol && webSocketOpened) {
-                    var time = atmosphere.util.now() - _request.ctime;
-                    _request.lastTimestamp = Number(_request.stime) + Number(time);
-                }
-
-                var location = _buildWebSocketUrl(_request.url);
-                if (_request.logLevel === 'debug') {
-                    atmosphere.util.debug("Invoking executeWebSocket");
-                    atmosphere.util.debug("Using URL: " + location);
-                }
-
-                if (webSocketOpened && !_request.reconnect) {
-                    if (_websocket != null) {
-                        _clearState();
-                    }
-                    return;
-                }
-
-                _websocket = _getWebSocket(location);
-                if (_request.webSocketBinaryType != null) {
-                    _websocket.binaryType = _request.webSocketBinaryType;
-                }
-
-                if (_request.connectTimeout > 0) {
-                    _request.id = setTimeout(function () {
-                        if (!webSocketOpened) {
-                            var _message = {
-                                code: 1002,
-                                reason: "",
-                                wasClean: false
-                            };
-                            _websocket.onclose(_message);
-                            // Close it anyway
-                            try {
-                                _clearState();
-                            } catch (e) {
-                            }
-                            return;
-                        }
-
-                    }, _request.connectTimeout);
-                }
-
-                _websocket.onopen = function (message) {
-                    _timeout(_request);
-
-                    if (_request.logLevel === 'debug') {
-                        atmosphere.util.debug("Websocket successfully opened");
-                    }
-
-                    var reopening = webSocketOpened;
-
-                    if(_websocket != null) {
-                        _websocket.canSendMessage = true;
-                    }
-
-                    if (!_request.enableProtocol) {
-                        webSocketOpened = true;
-                        if (reopening) {
-                            _open('re-opening', "websocket", _request);
-                        } else {
-                            _open('opening', "websocket", _request);
-                        }
-                    }
-
-                    if (_websocket != null) {
-                        if (_request.method === 'POST') {
-                            _response.state = "messageReceived";
-                            _websocket.send(_request.data);
-                        }
-                    }
-                };
-
-                _websocket.onmessage = function (message) {
-                    _timeout(_request);
-
-                    // We only consider it opened if we get the handshake data
-                    // https://github.com/Atmosphere/atmosphere-javascript/issues/74
-                    if (_request.enableProtocol) {
-                        webSocketOpened = true;
-                    }
-
-                    _response.state = 'messageReceived';
-                    _response.status = 200;
-
-                    message = message.data;
-                    var isString = typeof (message) === 'string';
-                    if (isString) {
-                        var skipCallbackInvocation = _trackMessageSize(message, _request, _response);
-                        if (!skipCallbackInvocation) {
-                            _invokeCallback();
-                            _response.responseBody = '';
-                            _response.messages = [];
-                        }
-                    } else {
-                        if (!_handleProtocol(_request, message))
-                            return;
-
-                        _response.responseBody = message;
-                        _invokeCallback();
-                        _response.responseBody = null;
-                    }
-                };
-
-                _websocket.onerror = function (message) {
-                    clearTimeout(_request.id);
-                };
-
-                _websocket.onclose = function (message) {
-                    clearTimeout(_request.id);
-                    if (_response.state === 'closed')
-                        return;
-
-                    var reason = message.reason;
-                    if (reason === "") {
-                        switch (message.code) {
-                            case 1000:
-                                reason = "Normal closure; the connection successfully completed whatever purpose for which " + "it was created.";
-                                break;
-                            case 1001:
-                                reason = "The endpoint is going away, either because of a server failure or because the "
-                                    + "browser is navigating away from the page that opened the connection.";
-                                break;
-                            case 1002:
-                                reason = "The endpoint is terminating the connection due to a protocol error.";
-                                break;
-                            case 1003:
-                                reason = "The connection is being terminated because the endpoint received data of a type it "
-                                    + "cannot accept (for example, a text-only endpoint received binary data).";
-                                break;
-                            case 1004:
-                                reason = "The endpoint is terminating the connection because a data frame was received that " + "is too large.";
-                                break;
-                            case 1005:
-                                reason = "Unknown: no status code was provided even though one was expected.";
-                                break;
-                            case 1006:
-                                reason = "Connection was closed abnormally (that is, with no close frame being sent).";
-                                break;
-                        }
-                    }
-
-                    if (_request.logLevel === 'warn') {
-                        atmosphere.util.warn("Websocket closed, reason: " + reason);
-                        atmosphere.util.warn("Websocket closed, wasClean: " + message.wasClean);
-                    }
-
-                    if (_response.closedByClientTimeout) {
-                        return;
-                    }
-
-                    _invokeClose(webSocketOpened);
-
-                    _response.state = 'closed';
-
-                    if (_abordingConnection) {
-                        atmosphere.util.log(_request.logLevel, ["Websocket closed normally"]);
-                    } else if (!webSocketOpened) {
-                        _reconnectWithFallbackTransport("Websocket failed. Downgrading to Comet and resending");
-
-                    } else if (_request.reconnect && _response.transport === 'websocket') {
-                        _clearState();
-                        if (_requestCount++ < _request.maxReconnectOnClose) {
-                            _open('re-connecting', _request.transport, _request);
-                            if (_request.reconnectInterval > 0) {
-                                _request.reconnectId = setTimeout(function () {
-                                    _response.responseBody = "";
-                                    _response.messages = [];
-                                    _executeWebSocket(true);
-                                }, _request.reconnectInterval);
-                            } else {
-                                _response.responseBody = "";
-                                _response.messages = [];
-                                _executeWebSocket(true);
-                            }
-                        } else {
-                            atmosphere.util.log(_request.logLevel, ["Websocket reconnect maximum try reached " + _request.requestCount]);
-                            if (_request.logLevel === 'warn') {
-                                atmosphere.util.warn("Websocket error, reason: " + message.reason);
-                            }
-                            _onError(0, "maxReconnectOnClose reached");
-                        }
-                    }
-                };
-
-                var ua = navigator.userAgent.toLowerCase();
-                var isAndroid = ua.indexOf("android") > -1;
-                if (isAndroid && _websocket.url === undefined) {
-                    // Android 4.1 does not really support websockets and fails silently
-                    _websocket.onclose({
-                        reason: "Android 4.1 does not support websockets.",
-                        wasClean: false
-                    });
-                }
-            }
-
-            function _handleProtocol(request, message) {
-
-                // The first messages is always the uuid.
-                var b = true;
-
-                if (request.transport === 'polling') return b;
-
-                if (atmosphere.util.trim(message).length !== 0 && request.enableProtocol && request.firstMessage) {
-                    request.firstMessage = false;
-                    var messages = message.split(request.messageDelimiter);
-                    var pos = messages.length === 2 ? 0 : 1;
-                    request.uuid = atmosphere.util.trim(messages[pos]);
-                    request.stime = atmosphere.util.trim(messages[pos + 1]);
-                    b = false;
-                    if (request.transport !== 'long-polling') {
-                        _triggerOpen(request);
-                    }
-                    uuid = request.uuid;
-                } else if (request.enableProtocol && request.firstMessage) {
-                    // In case we are getting some junk from IE
-                    b = false;
-                } else {
-                    _triggerOpen(request);
-                }
-                return b;
-            }
-
-            function _timeout(_request) {
-                clearTimeout(_request.id);
-                if (_request.timeout > 0 && _request.transport !== 'polling') {
-                    _request.id = setTimeout(function () {
-                        _onClientTimeout(_request);
-                        _disconnect();
-                        _clearState();
-                    }, _request.timeout);
-                }
-            }
-
-            function _onClientTimeout(_request) {
-                _response.closedByClientTimeout = true;
-                _response.state = 'closedByClient';
-                _response.responseBody = "";
-                _response.status = 408;
-                _response.messages = [];
-                _invokeCallback();
-            }
-
-            function _onError(code, reason) {
-                _clearState();
-                clearTimeout(_request.id);
-                _response.state = 'error';
-                _response.reasonPhrase = reason;
-                _response.responseBody = "";
-                _response.status = code;
-                _response.messages = [];
-                _invokeCallback();
-            }
-
-            /**
-             * Track received message and make sure callbacks/functions are only invoked when the complete message has been received.
-             *
-             * @param message
-             * @param request
-             * @param response
-             */
-            function _trackMessageSize(message, request, response) {
-                if (!_handleProtocol(request, message))
-                    return true;
-                if (message.length === 0)
-                    return true;
-
-                if (request.trackMessageLength) {
-                    // prepend partialMessage if any
-                    message = response.partialMessage + message;
-
-                    var messages = [];
-                    var messageStart = message.indexOf(request.messageDelimiter);
-                    while (messageStart !== -1) {
-                        var str = atmosphere.util.trim(message.substring(0, messageStart));
-                        var messageLength = +str;
-                        if (isNaN(messageLength))
-                            throw new Error('message length "' + str + '" is not a number');
-                        messageStart += request.messageDelimiter.length;
-                        if (messageStart + messageLength > message.length) {
-                            // message not complete, so there is no trailing messageDelimiter
-                            messageStart = -1;
-                        } else {
-                            // message complete, so add it
-                            messages.push(message.substring(messageStart, messageStart + messageLength));
-                            // remove consumed characters
-                            message = message.substring(messageStart + messageLength, message.length);
-                            messageStart = message.indexOf(request.messageDelimiter);
-                        }
-                    }
-
-                    /* keep any remaining data */
-                    response.partialMessage = message;
-
-                    if (messages.length !== 0) {
-                        response.responseBody = messages.join(request.messageDelimiter);
-                        response.messages = messages;
-                        return false;
-                    } else {
-                        response.responseBody = "";
-                        response.messages = [];
-                        return true;
-                    }
-                } else {
-                    response.responseBody = message;
-                }
-                return false;
-            }
-
-            /**
-             * Reconnect request with fallback transport. <br>
-             * Used in case websocket can't be opened.
-             *
-             * @private
-             */
-            function _reconnectWithFallbackTransport(errorMessage) {
-                atmosphere.util.log(_request.logLevel, [errorMessage]);
-
-                if (typeof (_request.onTransportFailure) !== 'undefined') {
-                    _request.onTransportFailure(errorMessage, _request);
-                } else if (typeof (atmosphere.util.onTransportFailure) !== 'undefined') {
-                    atmosphere.util.onTransportFailure(errorMessage, _request);
-                }
-
-                _request.transport = _request.fallbackTransport;
-                var reconnectInterval = _request.connectTimeout === -1 ? 0 : _request.connectTimeout;
-                if (_request.reconnect && _request.transport !== 'none' || _request.transport == null) {
-                    _request.method = _request.fallbackMethod;
-                    _response.transport = _request.fallbackTransport;
-                    _request.fallbackTransport = 'none';
-                    if (reconnectInterval > 0) {
-                        _request.reconnectId = setTimeout(function () {
-                            _execute();
-                        }, reconnectInterval);
-                    } else {
-                        _execute();
-                    }
-                } else {
-                    _onError(500, "Unable to reconnect with fallback transport");
-                }
-            }
-
-            /**
-             * Get url from request and attach headers to it.
-             *
-             * @param request {Object} request Request parameters, if undefined _request object will be used.
-             *
-             * @returns {Object} Request object, if undefined, _request object will be used.
-             * @private
-             */
-            function _attachHeaders(request, url) {
-                var rq = _request;
-                if ((request != null) && (typeof (request) !== 'undefined')) {
-                    rq = request;
-                }
-
-                if (url == null) {
-                    url = rq.url;
-                }
-
-                // If not enabled
-                if (!rq.attachHeadersAsQueryString)
-                    return url;
-
-                // If already added
-                if (url.indexOf("X-Atmosphere-Framework") !== -1) {
-                    return url;
-                }
-
-                url += (url.indexOf('?') !== -1) ? '&' : '?';
-                url += "X-Atmosphere-tracking-id=" + rq.uuid;
-                url += "&X-Atmosphere-Framework=" + version;
-                url += "&X-Atmosphere-Transport=" + rq.transport;
-
-                if (rq.trackMessageLength) {
-                    url += "&X-Atmosphere-TrackMessageSize=" + "true";
-                }
-
-                if (rq.lastTimestamp != null) {
-                    url += "&X-Cache-Date=" + rq.lastTimestamp;
-                } else {
-                    url += "&X-Cache-Date=" + 0;
-                }
-
-                if (rq.contentType !== '') {
-                    //Eurk!
-                    url += "&Content-Type=" + (rq.transport === 'websocket' ? rq.contentType : encodeURIComponent(rq.contentType));
-                }
-
-                if (rq.enableProtocol) {
-                    url += "&X-atmo-protocol=true";
-                }
-
-                atmosphere.util.each(rq.headers, function (name, value) {
-                    var h = atmosphere.util.isFunction(value) ? value.call(this, rq, request, _response) : value;
-                    if (h != null) {
-                        url += "&" + encodeURIComponent(name) + "=" + encodeURIComponent(h);
-                    }
-                });
-
-                return url;
-            }
-
-            function _triggerOpen(rq) {
-                if (!rq.isOpen) {
-                    rq.isOpen = true;
-                    _open('opening', rq.transport, rq);
-                } else if (rq.isReopen) {
-                    rq.isReopen = false;
-                    _open('re-opening', rq.transport, rq);
-                }
-            }
-
-            /**
-             * Execute ajax request. <br>
-             *
-             * @param request {Object} request Request parameters, if undefined _request object will be used.
-             * @private
-             */
-            function _executeRequest(request) {
-                var rq = _request;
-                if ((request != null) || (typeof (request) !== 'undefined')) {
-                    rq = request;
-                }
-
-                rq.lastIndex = 0;
-                rq.readyState = 0;
-
-                // CORS fake using JSONP
-                if ((rq.transport === 'jsonp') || ((rq.enableXDR) && (atmosphere.util.checkCORSSupport()))) {
-                    _jsonp(rq);
-                    return;
-                }
-
-                if (atmosphere.util.browser.msie && +atmosphere.util.browser.version.split(".")[0] < 10) {
-                    if ((rq.transport === 'streaming')) {
-                        if (rq.enableXDR && window.XDomainRequest) {
-                            _ieXDR(rq);
-                        } else {
-                            _ieStreaming(rq);
-                        }
-                        return;
-                    }
-
-                    if ((rq.enableXDR) && (window.XDomainRequest)) {
-                        _ieXDR(rq);
-                        return;
-                    }
-                }
-
-                var reconnectF = function () {
-                    rq.lastIndex = 0;
-                    if (rq.reconnect && _requestCount++ < rq.maxReconnectOnClose) {
-                        _open('re-connecting', request.transport, request);
-                        _reconnect(ajaxRequest, rq, request.reconnectInterval);
-                    } else {
-                        _onError(0, "maxReconnectOnClose reached");
-                    }
-                };
-
-                if (rq.force || (rq.reconnect && (rq.maxRequest === -1 || rq.requestCount++ < rq.maxRequest))) {
-                    rq.force = false;
-
-                    var ajaxRequest = atmosphere.util.xhr();
-                    ajaxRequest.hasData = false;
-
-                    _doRequest(ajaxRequest, rq, true);
-
-                    if (rq.suspend) {
-                        _activeRequest = ajaxRequest;
-                    }
-
-                    if (rq.transport !== 'polling') {
-                        _response.transport = rq.transport;
-
-                        ajaxRequest.onabort = function () {
-                            _invokeClose(true);
-                        };
-
-                        ajaxRequest.onerror = function () {
-                            _response.error = true;
-                            try {
-                                _response.status = XMLHttpRequest.status;
-                            } catch (e) {
-                                _response.status = 500;
-                            }
-
-                            if (!_response.status) {
-                                _response.status = 500;
-                            }
-                            if (!_response.errorHandled) {
-                                _clearState();
-                                reconnectF();
-                            }
-                        };
-                    }
-
-                    ajaxRequest.onreadystatechange = function () {
-                        if (_abordingConnection) {
-                            return;
-                        }
-
-                        _response.error = null;
-                        var skipCallbackInvocation = false;
-                        var update = false;
-
-                        if (rq.transport === 'streaming' && rq.readyState > 2 && ajaxRequest.readyState === 4) {
-                            if (rq.reconnectingOnLength) {
-                                return;
-                            }
-                            _clearState();
-                            reconnectF();
-                            return;
-                        }
-
-                        rq.readyState = ajaxRequest.readyState;
-
-                        if (rq.transport === 'streaming' && ajaxRequest.readyState >= 3) {
-                            update = true;
-                        } else if (rq.transport === 'long-polling' && ajaxRequest.readyState === 4) {
-                            update = true;
-                        }
-                        _timeout(_request);
-
-                        if (rq.transport !== 'polling') {
-                            // MSIE 9 and lower status can be higher than 1000, Chrome can be 0
-                            var status = 200;
-                            if (ajaxRequest.readyState === 4) {
-                                status = ajaxRequest.status > 1000 ? 0 : ajaxRequest.status;
-                            }
-
-                            if (status >= 300 || status === 0) {
-                                // Prevent onerror callback to be called
-                                _response.errorHandled = true;
-                                _clearState();
-                                reconnectF();
-                                return;
-                            }
-
-                            // Firefox incorrectly send statechange 0->2 when a reconnect attempt fails. The above checks ensure that onopen is not called for these
-                            if ((!rq.enableProtocol || !request.firstMessage) && ajaxRequest.readyState === 2) {
-                                _triggerOpen(rq);
-                            }
-
-                        } else if (ajaxRequest.readyState === 4) {
-                            update = true;
-                        }
-
-                        if (update) {
-                            var responseText = ajaxRequest.responseText;
-
-                            if (atmosphere.util.trim(responseText).length === 0 && rq.transport === 'long-polling') {
-                                // For browser that aren't support onabort
-                                if (!ajaxRequest.hasData) {
-                                    _reconnect(ajaxRequest, rq, rq.pollingInterval);
-                                } else {
-                                    ajaxRequest.hasData = false;
-                                }
-                                return;
-                            }
-                            ajaxRequest.hasData = true;
-
-                            _readHeaders(ajaxRequest, _request);
-
-                            if (rq.transport === 'streaming') {
-                                if (!atmosphere.util.browser.opera) {
-                                    var message = responseText.substring(rq.lastIndex, responseText.length);
-                                    skipCallbackInvocation = _trackMessageSize(message, rq, _response);
-
-                                    rq.lastIndex = responseText.length;
-                                    if (skipCallbackInvocation) {
-                                        return;
-                                    }
-                                } else {
-                                    atmosphere.util.iterate(function () {
-                                        if (_response.status !== 500 && ajaxRequest.responseText.length > rq.lastIndex) {
-                                            try {
-                                                _response.status = ajaxRequest.status;
-                                                _response.headers = atmosphere.util.parseHeaders(ajaxRequest.getAllResponseHeaders());
-
-                                                _readHeaders(ajaxRequest, _request);
-
-                                            } catch (e) {
-                                                _response.status = 404;
-                                            }
-                                            _timeout(_request);
-
-                                            _response.state = "messageReceived";
-                                            var message = ajaxRequest.responseText.substring(rq.lastIndex);
-                                            rq.lastIndex = ajaxRequest.responseText.length;
-
-                                            skipCallbackInvocation = _trackMessageSize(message, rq, _response);
-                                            if (!skipCallbackInvocation) {
-                                                _invokeCallback();
-                                            }
-
-                                            _verifyStreamingLength(ajaxRequest, rq);
-                                        } else if (_response.status > 400) {
-                                            // Prevent replaying the last message.
-                                            rq.lastIndex = ajaxRequest.responseText.length;
-                                            return false;
-                                        }
-                                    }, 0);
-                                }
-                            } else {
-                                skipCallbackInvocation = _trackMessageSize(responseText, rq, _response);
-                            }
-
-                            try {
-                                _response.status = ajaxRequest.status;
-                                _response.headers = atmosphere.util.parseHeaders(ajaxRequest.getAllResponseHeaders());
-
-                                _readHeaders(ajaxRequest, rq);
-                            } catch (e) {
-                                _response.status = 404;
-                            }
-
-                            if (rq.suspend) {
-                                _response.state = _response.status === 0 ? "closed" : "messageReceived";
-                            } else {
-                                _response.state = "messagePublished";
-                            }
-
-                            var isAllowedToReconnect = request.transport !== 'streaming' && request.transport !== 'polling';
-                            if (isAllowedToReconnect && !rq.executeCallbackBeforeReconnect) {
-                                _reconnect(ajaxRequest, rq, rq.pollingInterval);
-                            }
-
-                            if (_response.responseBody.length !== 0 && !skipCallbackInvocation)
-                                _invokeCallback();
-
-                            if (isAllowedToReconnect && rq.executeCallbackBeforeReconnect) {
-                                _reconnect(ajaxRequest, rq, rq.pollingInterval);
-                            }
-
-                            _verifyStreamingLength(ajaxRequest, rq);
-                        }
-                    };
-
-                    try {
-                        ajaxRequest.send(rq.data);
-                        _subscribed = true;
-                    } catch (e) {
-                        atmosphere.util.log(rq.logLevel, ["Unable to connect to " + rq.url]);
-                        _onError(0, e);
-                    }
-
-                } else {
-                    if (rq.logLevel === 'debug') {
-                        atmosphere.util.log(rq.logLevel, ["Max re-connection reached."]);
-                    }
-                    _onError(0, "maxRequest reached");
-                }
-            }
-
-            /**
-             * Do ajax request.
-             *
-             * @param ajaxRequest Ajax request.
-             * @param request Request parameters.
-             * @param create If ajax request has to be open.
-             */
-            function _doRequest(ajaxRequest, request, create) {
-                // Prevent Android to cache request
-                var url = request.url;
-                if (request.dispatchUrl != null && request.method === 'POST') {
-                    url += request.dispatchUrl;
-                }
-                url = _attachHeaders(request, url);
-                url = atmosphere.util.prepareURL(url);
-
-                if (create) {
-                    ajaxRequest.open(request.method, url, request.async);
-                    if (request.connectTimeout > 0) {
-                        request.id = setTimeout(function () {
-                            if (request.requestCount === 0) {
-                                _clearState();
-                                _prepareCallback("Connect timeout", "closed", 200, request.transport);
-                            }
-                        }, request.connectTimeout);
-                    }
-                }
-
-                if (_request.withCredentials) {
-                    if ("withCredentials" in ajaxRequest) {
-                        ajaxRequest.withCredentials = true;
-                    }
-                }
-
-                if (!_request.dropHeaders) {
-                    ajaxRequest.setRequestHeader("X-Atmosphere-Framework", atmosphere.util.version);
-                    ajaxRequest.setRequestHeader("X-Atmosphere-Transport", request.transport);
-                    if (request.lastTimestamp != null) {
-                        ajaxRequest.setRequestHeader("X-Cache-Date", request.lastTimestamp);
-                    } else {
-                        ajaxRequest.setRequestHeader("X-Cache-Date", 0);
-                    }
-
-                    if (request.trackMessageLength) {
-                        ajaxRequest.setRequestHeader("X-Atmosphere-TrackMessageSize", "true");
-                    }
-                    ajaxRequest.setRequestHeader("X-Atmosphere-tracking-id", request.uuid);
-
-                    atmosphere.util.each(request.headers, function (name, value) {
-                        var h = atmosphere.util.isFunction(value) ? value.call(this, ajaxRequest, request, create, _response) : value;
-                        if (h != null) {
-                            ajaxRequest.setRequestHeader(name, h);
-                        }
-                    });
-                }
-
-                if (request.contentType !== '') {
-                    ajaxRequest.setRequestHeader("Content-Type", request.contentType);
-                }
-            }
-
-            function _reconnect(ajaxRequest, request, reconnectInterval) {
-                if (request.reconnect || (request.suspend && _subscribed)) {
-                    var status = 0;
-                    if (ajaxRequest && ajaxRequest.readyState > 1) {
-                        status = ajaxRequest.status > 1000 ? 0 : ajaxRequest.status;
-                    }
-                    _response.status = status === 0 ? 204 : status;
-                    _response.reason = status === 0 ? "Server resumed the connection or down." : "OK";
-
-                    clearTimeout(request.id);
-                    if (request.reconnectId) {
-                        clearTimeout(request.reconnectId);
-                        delete request.reconnectId;
-                    }
-
-                    if (reconnectInterval > 0) {
-                        // For whatever reason, never cancel a reconnect timeout as it is mandatory to reconnect.
-                        _request.reconnectId = setTimeout(function () {
-                            _executeRequest(request);
-                        }, reconnectInterval);
-                    } else {
-                        _executeRequest(request);
-                    }
-                }
-            }
-
-            function _tryingToReconnect(response) {
-                response.state = 're-connecting';
-                _invokeFunction(response);
-            }
-
-            function _ieXDR(request) {
-                if (request.transport !== "polling") {
-                    _ieStream = _configureXDR(request);
-                    _ieStream.open();
-                } else {
-                    _configureXDR(request).open();
-                }
-            }
-
-            function _configureXDR(request) {
-                var rq = _request;
-                if ((request != null) && (typeof (request) !== 'undefined')) {
-                    rq = request;
-                }
-
-                var transport = rq.transport;
-                var lastIndex = 0;
-                var xdr = new window.XDomainRequest();
-
-                var reconnect = function () {
-                    if (rq.transport === "long-polling" && (rq.reconnect && (rq.maxRequest === -1 || rq.requestCount++ < rq.maxRequest))) {
-                        xdr.status = 200;
-                        _ieXDR(rq);
-                    }
-                };
-
-                var rewriteURL = rq.rewriteURL || function (url) {
-                    // Maintaining session by rewriting URL
-                    // http://stackoverflow.com/questions/6453779/maintaining-session-by-rewriting-url
-                    var match = /(?:^|;\s*)(JSESSIONID|PHPSESSID)=([^;]*)/.exec(document.cookie);
-
-                    switch (match && match[1]) {
-                        case "JSESSIONID":
-                            return url.replace(/;jsessionid=[^\?]*|(\?)|$/, ";jsessionid=" + match[2] + "$1");
-                        case "PHPSESSID":
-                            return url.replace(/\?PHPSESSID=[^&]*&?|\?|$/, "?PHPSESSID=" + match[2] + "&").replace(/&$/, "");
-                    }
-                    return url;
-                };
-
-                // Handles open and message event
-                xdr.onprogress = function () {
-                    handle(xdr);
-                };
-                // Handles error event
-                xdr.onerror = function () {
-                    // If the server doesn't send anything back to XDR will fail with polling
-                    if (rq.transport !== 'polling') {
-                        _clearState();
-                        if (_requestCount++ < rq.maxReconnectOnClose) {
-                            if (rq.reconnectInterval > 0) {
-                                rq.reconnectId = setTimeout(function () {
-                                    _open('re-connecting', request.transport, request);
-                                    _ieXDR(rq);
-                                }, rq.reconnectInterval);
-                            } else {
-                                _open('re-connecting', request.transport, request);
-                                _ieXDR(rq);
-                            }
-                        } else {
-                            _onError(0, "maxReconnectOnClose reached");
-                        }
-                    }
-                };
-
-                // Handles close event
-                xdr.onload = function () {
-                };
-
-                var handle = function (xdr) {
-                    clearTimeout(rq.id);
-                    var message = xdr.responseText;
-
-                    message = message.substring(lastIndex);
-                    lastIndex += message.length;
-
-                    if (transport !== 'polling') {
-                        _timeout(rq);
-
-                        var skipCallbackInvocation = _trackMessageSize(message, rq, _response);
-
-                        if (transport === 'long-polling' && atmosphere.util.trim(message).length === 0)
-                            return;
-
-                        if (rq.executeCallbackBeforeReconnect) {
-                            reconnect();
-                        }
-
-                        if (!skipCallbackInvocation) {
-                            _prepareCallback(_response.responseBody, "messageReceived", 200, transport);
-                        }
-
-                        if (!rq.executeCallbackBeforeReconnect) {
-                            reconnect();
-                        }
-                    }
-                };
-
-                return {
-                    open: function () {
-                        var url = rq.url;
-                        if (rq.dispatchUrl != null) {
-                            url += rq.dispatchUrl;
-                        }
-                        url = _attachHeaders(rq, url);
-                        xdr.open(rq.method, rewriteURL(url));
-                        if (rq.method === 'GET') {
-                            xdr.send();
-                        } else {
-                            xdr.send(rq.data);
-                        }
-
-                        if (rq.connectTimeout > 0) {
-                            rq.id = setTimeout(function () {
-                                if (rq.requestCount === 0) {
-                                    _clearState();
-                                    _prepareCallback("Connect timeout", "closed", 200, rq.transport);
-                                }
-                            }, rq.connectTimeout);
-                        }
-                    },
-                    close: function () {
-                        xdr.abort();
-                    }
-                };
-            }
-
-            function _ieStreaming(request) {
-                _ieStream = _configureIE(request);
-                _ieStream.open();
-            }
-
-            function _configureIE(request) {
-                var rq = _request;
-                if ((request != null) && (typeof (request) !== 'undefined')) {
-                    rq = request;
-                }
-
-                var stop;
-                var doc = new window.ActiveXObject("htmlfile");
-
-                doc.open();
-                doc.close();
-
-                var url = rq.url;
-                if (rq.dispatchUrl != null) {
-                    url += rq.dispatchUrl;
-                }
-
-                if (rq.transport !== 'polling') {
-                    _response.transport = rq.transport;
-                }
-
-                return {
-                    open: function () {
-                        var iframe = doc.createElement("iframe");
-
-                        url = _attachHeaders(rq);
-                        if (rq.data !== '') {
-                            url += "&X-Atmosphere-Post-Body=" + encodeURIComponent(rq.data);
-                        }
-
-                        // Finally attach a timestamp to prevent Android and IE caching.
-                        url = atmosphere.util.prepareURL(url);
-
-                        iframe.src = url;
-                        doc.body.appendChild(iframe);
-
-                        // For the server to respond in a consistent format regardless of user agent, we polls response text
-                        var cdoc = iframe.contentDocument || iframe.contentWindow.document;
-
-                        stop = atmosphere.util.iterate(function () {
-                            try {
-                                if (!cdoc.firstChild) {
-                                    return;
-                                }
-
-                                var res = cdoc.body ? cdoc.body.lastChild : cdoc;
-                                var readResponse = function () {
-                                    // Clones the element not to disturb the original one
-                                    var clone = res.cloneNode(true);
-
-                                    // If the last character is a carriage return or a line feed, IE ignores it in the innerText property
-                                    // therefore, we add another non-newline character to preserve it
-                                    clone.appendChild(cdoc.createTextNode("."));
-
-                                    var text = clone.innerText;
-
-                                    text = text.substring(0, text.length - 1);
-                                    return text;
-
-                                };
-
-                                // To support text/html content type
-                                if (!cdoc.body || !cdoc.body.firstChild || cdoc.body.firstChild.nodeName.toLowerCase() !== "pre") {
-                                    // Injects a plaintext element which renders text without interpreting the HTML and cannot be stopped
-                                    // it is deprecated in HTML5, but still works
-                                    var head = cdoc.head || cdoc.getElementsByTagName("head")[0] || cdoc.documentElement || cdoc;
-                                    var script = cdoc.createElement("script");
-
-                                    script.text = "document.write('<plaintext>')";
-
-                                    head.insertBefore(script, head.firstChild);
-                                    head.removeChild(script);
-
-                                    // The plaintext element will be the response container
-                                    res = cdoc.body.lastChild;
-                                }
-
-                                if (rq.closed) {
-                                    rq.isReopen = true;
-                                }
-
-                                // Handles message and close event
-                                stop = atmosphere.util.iterate(function () {
-                                    var text = readResponse();
-                                    if (text.length > rq.lastIndex) {
-                                        _timeout(_request);
-
-                                        _response.status = 200;
-                                        _response.error = null;
-
-                                        // Empties response every time that it is handled
-                                        res.innerText = "";
-                                        var skipCallbackInvocation = _trackMessageSize(text, rq, _response);
-                                        if (skipCallbackInvocation) {
-                                            return "";
-                                        }
-
-                                        _prepareCallback(_response.responseBody, "messageReceived", 200, rq.transport);
-                                    }
-
-                                    rq.lastIndex = 0;
-
-                                    if (cdoc.readyState === "complete") {
-                                        _invokeClose(true);
-                                        _open('re-connecting', rq.transport, rq);
-                                        if (rq.reconnectInterval > 0) {
-                                            rq.reconnectId = setTimeout(function () {
-                                                _ieStreaming(rq);
-                                            }, rq.reconnectInterval);
-                                        } else {
-                                            _ieStreaming(rq);
-                                        }
-                                        return false;
-                                    }
-                                }, null);
-
-                                return false;
-                            } catch (err) {
-                                _response.error = true;
-                                _open('re-connecting', rq.transport, rq);
-                                if (_requestCount++ < rq.maxReconnectOnClose) {
-                                    if (rq.reconnectInterval > 0) {
-                                        rq.reconnectId = setTimeout(function () {
-                                            _ieStreaming(rq);
-                                        }, rq.reconnectInterval);
-                                    } else {
-                                        _ieStreaming(rq);
-                                    }
-                                } else {
-                                    _onError(0, "maxReconnectOnClose reached");
-                                }
-                                doc.execCommand("Stop");
-                                doc.close();
-                                return false;
-                            }
-                        });
-                    },
-
-                    close: function () {
-                        if (stop) {
-                            stop();
-                        }
-
-                        doc.execCommand("Stop");
-                        _invokeClose(true);
-                    }
-                };
-            }
-
-            /**
-             * Send message. <br>
-             * Will be automatically dispatch to other connected.
-             *
-             * @param {Object, string} Message to send.
-             * @private
-             */
-            function _push(message) {
-
-                if (_localStorageService != null) {
-                    _pushLocal(message);
-                } else if (_activeRequest != null || _sse != null) {
-                    _pushAjaxMessage(message);
-                } else if (_ieStream != null) {
-                    _pushIE(message);
-                } else if (_jqxhr != null) {
-                    _pushJsonp(message);
-                } else if (_websocket != null) {
-                    _pushWebSocket(message);
-                } else {
-                    _onError(0, "No suspended connection available");
-                    atmosphere.util.error("No suspended connection available. Make sure atmosphere.subscribe has been called and request.onOpen invoked before invoking this method");
-                }
-            }
-
-            function _pushOnClose(message, rq) {
-                if (!rq) {
-                    rq = _getPushRequest(message);
-                }
-                rq.transport = "polling";
-                rq.method = "GET";
-                rq.async = false;
-                rq.withCredentials = false;
-                rq.reconnect = false;
-                rq.force = true;
-                rq.suspend = false;
-                rq.timeout = 1000;
-                _executeRequest(rq);
-            }
-
-            function _pushLocal(message) {
-                _localStorageService.send(message);
-            }
-
-            function _intraPush(message) {
-                // IE 9 will crash if not.
-                if (message.length === 0)
-                    return;
-
-                try {
-                    if (_localStorageService) {
-                        _localStorageService.localSend(message);
-                    } else if (_storageService) {
-                        _storageService.signal("localMessage", atmosphere.util.stringifyJSON({
-                            id: guid,
-                            event: message
-                        }));
-                    }
-                } catch (err) {
-                    atmosphere.util.error(err);
-                }
-            }
-
-            /**
-             * Send a message using currently opened ajax request (using http-streaming or long-polling). <br>
-             *
-             * @param {string, Object} Message to send. This is an object, string message is saved in data member.
-             * @private
-             */
-            function _pushAjaxMessage(message) {
-                var rq = _getPushRequest(message);
-                _executeRequest(rq);
-            }
-
-            /**
-             * Send a message using currently opened ie streaming (using http-streaming or long-polling). <br>
-             *
-             * @param {string, Object} Message to send. This is an object, string message is saved in data member.
-             * @private
-             */
-            function _pushIE(message) {
-                if (_request.enableXDR && atmosphere.util.checkCORSSupport()) {
-                    var rq = _getPushRequest(message);
-                    // Do not reconnect since we are pushing.
-                    rq.reconnect = false;
-                    _jsonp(rq);
-                } else {
-                    _pushAjaxMessage(message);
-                }
-            }
-
-            /**
-             * Send a message using jsonp transport. <br>
-             *
-             * @param {string, Object} Message to send. This is an object, string message is saved in data member.
-             * @private
-             */
-            function _pushJsonp(message) {
-                _pushAjaxMessage(message);
-            }
-
-            function _getStringMessage(message) {
-                var msg = message;
-                if (typeof (msg) === 'object') {
-                    msg = message.data;
-                }
-                return msg;
-            }
-
-            /**
-             * Build request use to push message using method 'POST' <br>. Transport is defined as 'polling' and 'suspend' is set to false.
-             *
-             * @return {Object} Request object use to push message.
-             * @private
-             */
-            function _getPushRequest(message) {
-                var msg = _getStringMessage(message);
-
-                var rq = {
-                    connected: false,
-                    timeout: 60000,
-                    method: 'POST',
-                    url: _request.url,
-                    contentType: _request.contentType,
-                    headers: _request.headers,
-                    reconnect: true,
-                    callback: null,
-                    data: msg,
-                    suspend: false,
-                    maxRequest: -1,
-                    logLevel: 'info',
-                    requestCount: 0,
-                    withCredentials: _request.withCredentials,
-                    async: _request.async,
-                    transport: 'polling',
-                    isOpen: true,
-                    attachHeadersAsQueryString: true,
-                    enableXDR: _request.enableXDR,
-                    uuid: _request.uuid,
-                    dispatchUrl: _request.dispatchUrl,
-                    enableProtocol: false,
-                    messageDelimiter: '|',
-                    maxReconnectOnClose: _request.maxReconnectOnClose
-                };
-
-                if (typeof (message) === 'object') {
-                    rq = atmosphere.util.extend(rq, message);
-                }
-
-                return rq;
-            }
-
-            /**
-             * Send a message using currently opened websocket. <br>
-             *
-             */
-            function _pushWebSocket(message) {
-                var msg = atmosphere.util.isBinary(message) ? message : _getStringMessage(message);
-                var data;
-                try {
-                    if (_request.dispatchUrl != null) {
-                        data = _request.webSocketPathDelimiter + _request.dispatchUrl + _request.webSocketPathDelimiter + msg;
-                    } else {
-                        data = msg;
-                    }
-
-                    if (!_websocket.canSendMessage) {
-                        atmosphere.util.error("WebSocket not connected.");
-                        return;
-                    }
-
-                    _websocket.send(data);
-
-                } catch (e) {
-                    _websocket.onclose = function (message) {
-                    };
-                    _clearState();
-
-                    _reconnectWithFallbackTransport("Websocket failed. Downgrading to Comet and resending " + message);
-                    _pushAjaxMessage(message);
-                }
-            }
-
-            function _localMessage(message) {
-                var m = atmosphere.util.parseJSON(message);
-                if (m.id !== guid) {
-                    if (typeof (_request.onLocalMessage) !== 'undefined') {
-                        _request.onLocalMessage(m.event);
-                    } else if (typeof (atmosphere.util.onLocalMessage) !== 'undefined') {
-                        atmosphere.util.onLocalMessage(m.event);
-                    }
-                }
-            }
-
-            function _prepareCallback(messageBody, state, errorCode, transport) {
-
-                _response.responseBody = messageBody;
-                _response.transport = transport;
-                _response.status = errorCode;
-                _response.state = state;
-
-                _invokeCallback();
-            }
-
-            function _readHeaders(xdr, request) {
-                if (!request.readResponsesHeaders) {
-                    if (!request.enableProtocol) {
-                        request.lastTimestamp = atmosphere.util.now();
-                        request.uuid = guid;
-                    }
-                }
-                else {
-                    try {
-                        var tempDate = xdr.getResponseHeader('X-Cache-Date');
-                        if (tempDate && tempDate != null && tempDate.length > 0) {
-                            request.lastTimestamp = tempDate.split(" ").pop();
-                        }
-
-                        var tempUUID = xdr.getResponseHeader('X-Atmosphere-tracking-id');
-                        if (tempUUID && tempUUID != null) {
-                            request.uuid = tempUUID.split(" ").pop();
-                        }
-                    } catch (e) {
-                    }
-                }
-            }
-
-            function _invokeFunction(response) {
-                _f(response, _request);
-                // Global
-                _f(response, atmosphere.util);
-            }
-
-            function _f(response, f) {
-                switch (response.state) {
-                    case "messageReceived":
-                        _requestCount = 0;
-                        if (typeof (f.onMessage) !== 'undefined')
-                            f.onMessage(response);
-                        break;
-                    case "error":
-                        if (typeof (f.onError) !== 'undefined')
-                            f.onError(response);
-                        break;
-                    case "opening":
-                        delete _request.closed;
-                        if (typeof (f.onOpen) !== 'undefined')
-                            f.onOpen(response);
-                        break;
-                    case "messagePublished":
-                        if (typeof (f.onMessagePublished) !== 'undefined')
-                            f.onMessagePublished(response);
-                        break;
-                    case "re-connecting":
-                        if (typeof (f.onReconnect) !== 'undefined')
-                            f.onReconnect(_request, response);
-                        break;
-                    case "closedByClient":
-                        if (typeof (f.onClientTimeout) !== 'undefined')
-                           f.onClientTimeout(_request);
-                        break;
-                    case "re-opening":
-                        delete _request.closed;
-                        if (typeof (f.onReopen) !== 'undefined')
-                            f.onReopen(_request, response);
-                        break;
-                    case "fail-to-reconnect":
-                        if (typeof (f.onFailureToReconnect) !== 'undefined')
-                            f.onFailureToReconnect(_request, response);
-                        break;
-                    case "unsubscribe":
-                    case "closed":
-                        var closed = typeof (_request.closed) !== 'undefined' ? _request.closed : false;
-                        if (typeof (f.onClose) !== 'undefined' && !closed)
-                            f.onClose(response);
-                        _request.closed = true;
-                        break;
-                }
-            }
-
-            function _invokeClose(wasOpen) {
-                if (_response.state !== 'closed') {
-                    _response.state = 'closed';
-                    _response.responseBody = "";
-                    _response.messages = [];
-                    _response.status = !wasOpen ? 501 : 200;
-                    _invokeCallback();
-                }
-            }
-
-            /**
-             * Invoke request callbacks.
-             *
-             * @private
-             */
-            function _invokeCallback() {
-                var call = function (index, func) {
-                    func(_response);
-                };
-
-                if (_localStorageService == null && _localSocketF != null) {
-                    _localSocketF(_response.responseBody);
-                }
-
-                _request.reconnect = _request.mrequest;
-
-                var isString = typeof (_response.responseBody) === 'string';
-                var messages = (isString && _request.trackMessageLength) ? (_response.messages.length > 0 ? _response.messages : ['']) : new Array(
-                    _response.responseBody);
-                for (var i = 0; i < messages.length; i++) {
-
-                    if (messages.length > 1 && messages[i].length === 0) {
-                        continue;
-                    }
-                    _response.responseBody = (isString) ? atmosphere.util.trim(messages[i]) : messages[i];
-
-                    if (_localStorageService == null && _localSocketF != null) {
-                        _localSocketF(_response.responseBody);
-                    }
-
-                    if (_response.responseBody.length === 0 && _response.state === "messageReceived") {
-                        continue;
-                    }
-
-                    _invokeFunction(_response);
-
-                    // Invoke global callbacks
-                    if (callbacks.length > 0) {
-                        if (_request.logLevel === 'debug') {
-                            atmosphere.util.debug("Invoking " + callbacks.length + " global callbacks: " + _response.state);
-                        }
-                        try {
-                            atmosphere.util.each(callbacks, call);
-                        } catch (e) {
-                            atmosphere.util.log(_request.logLevel, ["Callback exception" + e]);
-                        }
-                    }
-
-                    // Invoke request callback
-                    if (typeof (_request.callback) === 'function') {
-                        if (_request.logLevel === 'debug') {
-                            atmosphere.util.debug("Invoking request callbacks");
-                        }
-                        try {
-                            _request.callback(_response);
-                        } catch (e) {
-                            atmosphere.util.log(_request.logLevel, ["Callback exception" + e]);
-                        }
-                    }
-                }
-            }
-
-            this.subscribe = function (options) {
-                _subscribe(options);
-                _execute();
-            };
-
-            this.execute = function () {
-                _execute();
-            };
-
-            this.close = function () {
-                _close();
-            };
-
-            this.disconnect = function () {
-                _disconnect();
-            };
-
-            this.getUrl = function () {
-                return _request.url;
-            };
-
-            this.push = function (message, dispatchUrl) {
-                if (dispatchUrl != null) {
-                    var originalDispatchUrl = _request.dispatchUrl;
-                    _request.dispatchUrl = dispatchUrl;
-                    _push(message);
-                    _request.dispatchUrl = originalDispatchUrl;
-                } else {
-                    _push(message);
-                }
-            };
-
-            this.getUUID = function () {
-                return _request.uuid;
-            };
-
-            this.pushLocal = function (message) {
-                _intraPush(message);
-            };
-
-            this.enableProtocol = function (message) {
-                return _request.enableProtocol;
-            };
-
-            this.request = _request;
-            this.response = _response;
-        }
-    };
-
-    atmosphere.subscribe = function (url, callback, request) {
-        if (typeof (callback) === 'function') {
-            atmosphere.addCallback(callback);
-        }
-
-        // https://github.com/Atmosphere/atmosphere-javascript/issues/58
-        uuid = 0;
-
-        if (typeof (url) !== "string") {
-            request = url;
-        } else {
-            request.url = url;
-        }
-
-        var rq = new atmosphere.AtmosphereRequest(request);
-        rq.execute();
-
-        requests[requests.length] = rq;
-        return rq;
-    };
-
-    atmosphere.unsubscribe = function () {
-        if (requests.length > 0) {
-            var requestsClone = [].concat(requests);
-            for (var i = 0; i < requestsClone.length; i++) {
-                var rq = requestsClone[i];
-                rq.close();
-                clearTimeout(rq.response.request.id);
-            }
-        }
-        requests = [];
-        callbacks = [];
-    };
-
-    atmosphere.unsubscribeUrl = function (url) {
-        var idx = -1;
-        if (requests.length > 0) {
-            for (var i = 0; i < requests.length; i++) {
-                var rq = requests[i];
-
-                // Suppose you can subscribe once to an url
-                if (rq.getUrl() === url) {
-                    rq.close();
-                    clearTimeout(rq.response.request.id);
-                    idx = i;
-                    break;
-                }
-            }
-        }
-        if (idx >= 0) {
-            requests.splice(idx, 1);
-        }
-    };
-
-    atmosphere.addCallback = function (func) {
-        if (atmosphere.util.inArray(func, callbacks) === -1) {
-            callbacks.push(func);
-        }
-    };
-
-    atmosphere.removeCallback = function (func) {
-        var index = atmosphere.util.inArray(func, callbacks);
-        if (index !== -1) {
-            callbacks.splice(index, 1);
-        }
-    };
-
-    atmosphere.util = {
-        browser: {},
-
-        parseHeaders: function (headerString) {
-            var match, rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, headers = {};
-            while (match = rheaders.exec(headerString)) {
-                headers[match[1]] = match[2];
-            }
-            return headers;
-        },
-
-        now: function () {
-            return new Date().getTime();
-        },
-
-        isArray: function (array) {
-            return Object.prototype.toString.call(array) === "[object Array]";
-        },
-
-        inArray: function (elem, array) {
-            if (!Array.prototype.indexOf) {
-                var len = array.length;
-                for (var i = 0; i < len; ++i) {
-                    if (array[i] === elem) {
-                        return i;
-                    }
-                }
-                return -1;
-            }
-            return array.indexOf(elem);
-        },
-
-        isBinary: function (data) {
-            // True if data is an instance of Blob, ArrayBuffer or ArrayBufferView 
-            return /^\[object\s(?:Blob|ArrayBuffer|.+Array)\]$/.test(Object.prototype.toString.call(data));
-        },
-
-        isFunction: function (fn) {
-            return Object.prototype.toString.call(fn) === "[object Function]";
-        },
-
-        getAbsoluteURL: function (url) {
-            var div = document.createElement("div");
-
-            // Uses an innerHTML property to obtain an absolute URL
-            div.innerHTML = '<a href="' + url + '"/>';
-
-            // encodeURI and decodeURI are needed to normalize URL between IE and non-IE,
-            // since IE doesn't encode the href property value and return it - http://jsfiddle.net/Yq9M8/1/
-            return encodeURI(decodeURI(div.firstChild.href));
-        },
-
-        prepareURL: function (url) {
-            // Attaches a time stamp to prevent caching
-            var ts = atmosphere.util.now();
-            var ret = url.replace(/([?&])_=[^&]*/, "$1_=" + ts);
-
-            return ret + (ret === url ? (/\?/.test(url) ? "&" : "?") + "_=" + ts : "");
-        },
-
-        trim: function (str) {
-            if (!String.prototype.trim) {
-                return str.toString().replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g, "").replace(/\s+/g, " ");
-            } else {
-                return str.toString().trim();
-            }
-        },
-
-        param: function (params) {
-            var prefix, s = [];
-
-            function add(key, value) {
-                value = atmosphere.util.isFunction(value) ? value() : (value == null ? "" : value);
-                s.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
-            }
-
-            function buildParams(prefix, obj) {
-                var name;
-
-                if (atmosphere.util.isArray(obj)) {
-                    atmosphere.util.each(obj, function (i, v) {
-                        if (/\[\]$/.test(prefix)) {
-                            add(prefix, v);
-                        } else {
-                            buildParams(prefix + "[" + (typeof v === "object" ? i : "") + "]", v);
-                        }
-                    });
-                } else if (Object.prototype.toString.call(obj) === "[object Object]") {
-                    for (name in obj) {
-                        buildParams(prefix + "[" + name + "]", obj[name]);
-                    }
-                } else {
-                    add(prefix, obj);
-                }
-            }
-
-            for (prefix in params) {
-                buildParams(prefix, params[prefix]);
-            }
-
-            return s.join("&").replace(/%20/g, "+");
-        },
-
-        storage: function () {
-        	try {
-        		return !!(window.localStorage && window.StorageEvent);
-        	} catch (e) {
-        		//Firefox throws an exception here, see 
-        		//https://bugzilla.mozilla.org/show_bug.cgi?id=748620
-        		return false;
-        	}
-        },
-
-        iterate: function (fn, interval) {
-            var timeoutId;
-
-            // Though the interval is 0 for real-time application, there is a delay between setTimeout calls
-            // For detail, see https://developer.mozilla.org/en/window.setTimeout#Minimum_delay_and_timeout_nesting
-            interval = interval || 0;
-
-            (function loop() {
-                timeoutId = setTimeout(function () {
-                    if (fn() === false) {
-                        return;
-                    }
-
-                    loop();
-                }, interval);
-            })();
-
-            return function () {
-                clearTimeout(timeoutId);
-            };
-        },
-
-        each: function (obj, callback, args) {
-            if (!obj) return;
-            var value, i = 0, length = obj.length, isArray = atmosphere.util.isArray(obj);
-
-            if (args) {
-                if (isArray) {
-                    for (; i < length; i++) {
-                        value = callback.apply(obj[i], args);
-
-                        if (value === false) {
-                            break;
-                        }
-                    }
-                } else {
-                    for (i in obj) {
-                        value = callback.apply(obj[i], args);
-
-                        if (value === false) {
-                            break;
-                        }
-                    }
-                }
-
-                // A special, fast, case for the most common use of each
-            } else {
-                if (isArray) {
-                    for (; i < length; i++) {
-                        value = callback.call(obj[i], i, obj[i]);
-
-                        if (value === false) {
-                            break;
-                        }
-                    }
-                } else {
-                    for (i in obj) {
-                        value = callback.call(obj[i], i, obj[i]);
-
-                        if (value === false) {
-                            break;
-                        }
-                    }
-                }
-            }
-
-            return obj;
-        },
-
-        extend: function (target) {
-            var i, options, name;
-
-            for (i = 1; i < arguments.length; i++) {
-                if ((options = arguments[i]) != null) {
-                    for (name in options) {
-                        target[name] = options[name];
-                    }
-                }
-            }
-
-            return target;
-        },
-        on: function (elem, type, fn) {
-            if (elem.addEventListener) {
-                elem.addEventListener(type, fn, false);
-            } else if (elem.attachEvent) {
-                elem.attachEvent("on" + type, fn);
-            }
-        },
-        off: function (elem, type, fn) {
-            if (elem.removeEventListener) {
-                elem.removeEventListener(type, fn, false);
-            } else if (elem.detachEvent) {
-                elem.detachEvent("on" + type, fn);
-            }
-        },
-
-        log: function (level, args) {
-            if (window.console) {
-                var logger = window.console[level];
-                if (typeof logger === 'function') {
-                    logger.apply(window.console, args);
-                }
-            }
-        },
-
-        warn: function () {
-            atmosphere.util.log('warn', arguments);
-        },
-
-        info: function () {
-            atmosphere.util.log('info', arguments);
-        },
-
-        debug: function () {
-            atmosphere.util.log('debug', arguments);
-        },
-
-        error: function () {
-            atmosphere.util.log('error', arguments);
-        },
-        xhr: function () {
-            try {
-                return new window.XMLHttpRequest();
-            } catch (e1) {
-                try {
-                    return new window.ActiveXObject("Microsoft.XMLHTTP");
-                } catch (e2) {
-                }
-            }
-        },
-        parseJSON: function (data) {
-            return !data ? null : window.JSON && window.JSON.parse ? window.JSON.parse(data) : new Function("return " + data)();
-        },
-        // http://github.com/flowersinthesand/stringifyJSON
-        stringifyJSON: function (value) {
-            var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, meta = {
-                '\b': '\\b',
-                '\t': '\\t',
-                '\n': '\\n',
-                '\f': '\\f',
-                '\r': '\\r',
-                '"': '\\"',
-                '\\': '\\\\'
-            };
-
-            function quote(string) {
-                return '"' + string.replace(escapable, function (a) {
-                    var c = meta[a];
-                    return typeof c === "string" ? c : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
-                }) + '"';
-            }
-
-            function f(n) {
-                return n < 10 ? "0" + n : n;
-            }
-
-            return window.JSON && window.JSON.stringify ? window.JSON.stringify(value) : (function str(key, holder) {
-                var i, v, len, partial, value = holder[key], type = typeof value;
-
-                if (value && typeof value === "object" && typeof value.toJSON === "function") {
-                    value = value.toJSON(key);
-                    type = typeof value;
-                }
-
-                switch (type) {
-                    case "string":
-                        return quote(value);
-                    case "number":
-                        return isFinite(value) ? String(value) : "null";
-                    case "boolean":
-                        return String(value);
-                    case "object":
-                        if (!value) {
-                            return "null";
-                        }
-
-                        switch (Object.prototype.toString.call(value)) {
-                            case "[object Date]":
-                                return isFinite(value.valueOf()) ? '"' + value.getUTCFullYear() + "-" + f(value.getUTCMonth() + 1) + "-"
-                                    + f(value.getUTCDate()) + "T" + f(value.getUTCHours()) + ":" + f(value.getUTCMinutes()) + ":" + f(value.getUTCSeconds())
-                                    + "Z" + '"' : "null";
-                            case "[object Array]":
-                                len = value.length;
-                                partial = [];
-                                for (i = 0; i < len; i++) {
-                                    partial.push(str(i, value) || "null");
-                                }
-
-                                return "[" + partial.join(",") + "]";
-                            default:
-                                partial = [];
-                                for (i in value) {
-                                    if (hasOwn.call(value, i)) {
-                                        v = str(i, value);
-                                        if (v) {
-                                            partial.push(quote(i) + ":" + v);
-                                        }
-                                    }
-                                }
-
-                                return "{" + partial.join(",") + "}";
-                        }
-                }
-            })("", {
-                "": value
-            });
-        },
-
-        checkCORSSupport: function () {
-            if (atmosphere.util.browser.msie && !window.XDomainRequest && +atmosphere.util.browser.version.split(".")[0] < 11) {
-                return true;
-            } else if (atmosphere.util.browser.opera && +atmosphere.util.browser.version.split(".") < 12.0) {
-                return true;
-            }
-
-            // KreaTV 4.1 -> 4.4
-            else if (atmosphere.util.trim(navigator.userAgent).slice(0, 16) === "KreaTVWebKit/531") {
-                return true;
-            }
-            // KreaTV 3.8
-            else if (atmosphere.util.trim(navigator.userAgent).slice(-7).toLowerCase() === "kreatel") {
-                return true;
-            }
-
-            // Force Android to use CORS as some version like 2.2.3 fail otherwise
-            var ua = navigator.userAgent.toLowerCase();
-            var isAndroid = ua.indexOf("android") > -1;
-            if (isAndroid) {
-                return true;
-            }
-            return false;
-        }
-    };
-
-    guid = atmosphere.util.now();
-
-    // Browser sniffing
-    (function () {
-        var ua = navigator.userAgent.toLowerCase(),
-            match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
-                /(webkit)[ \/]([\w.]+)/.exec(ua) ||
-                /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
-                /(msie) ([\w.]+)/.exec(ua) ||
-                /(trident)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
-                ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
-                [];
-
-        atmosphere.util.browser[match[1] || ""] = true;
-        atmosphere.util.browser.version = match[2] || "0";
-        
-        // Trident is the layout engine of the Internet Explorer
-        // IE 11 has no "MSIE: 11.0" token
-        if (atmosphere.util.browser.trident) {
-            atmosphere.util.browser.msie = true;
-        }
-
-        // The storage event of Internet Explorer and Firefox 3 works strangely
-        if (atmosphere.util.browser.msie || (atmosphere.util.browser.mozilla && +atmosphere.util.browser.version.split(".")[0] === 1)) {
-            atmosphere.util.storage = false;
-        }
-    })();
-
-    atmosphere.util.on(window, "unload", function (event) {
-        atmosphere.unsubscribe();
-    });
-
-    // Pressing ESC key in Firefox kills the connection
-    // for your information, this is fixed in Firefox 20
-    // https://bugzilla.mozilla.org/show_bug.cgi?id=614304
-    atmosphere.util.on(window, "keypress", function (event) {
-        if (event.charCode === 27 || event.keyCode === 27) {
-            if (event.preventDefault) {
-                event.preventDefault();
-            }
-        }
-    });
-
-    atmosphere.util.on(window, "offline", function () {
-        atmosphere.unsubscribe();
-    });
-    
-    return atmosphere;
-}));
-/* jshint eqnull:true, noarg:true, noempty:true, eqeqeq:true, evil:true, laxbreak:true, undef:true, browser:true, indent:false, maxerr:50 */
diff --git a/wave/src/main/java/org/waveprotocol/box/server/rpc/ServerRpcProvider.java b/wave/src/main/java/org/waveprotocol/box/server/rpc/ServerRpcProvider.java
index c256199..8d59a61 100755
--- a/wave/src/main/java/org/waveprotocol/box/server/rpc/ServerRpcProvider.java
+++ b/wave/src/main/java/org/waveprotocol/box/server/rpc/ServerRpcProvider.java
@@ -19,6 +19,53 @@
 
 package org.waveprotocol.box.server.rpc;
 
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+
+import javax.annotation.Nullable;
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.ServletContextListener;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.lang.StringUtils;
+import org.eclipse.jetty.proxy.ProxyServlet;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.session.HashSessionManager;
+import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.servlets.GzipFilter;
+import org.eclipse.jetty.util.resource.ResourceCollection;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
+import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
+import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
+import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
+import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
+import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolAuthenticate;
+import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolAuthenticationResult;
+import org.waveprotocol.box.server.authentication.SessionManager;
+import org.waveprotocol.box.server.executor.ExecutorAnnotations.ClientServerExecutor;
+import org.waveprotocol.box.server.persistence.file.FileUtils;
+import org.waveprotocol.box.server.util.NetUtils;
+import org.waveprotocol.box.stat.Timer;
+import org.waveprotocol.box.stat.Timing;
+import org.waveprotocol.wave.model.util.Pair;
+import org.waveprotocol.wave.model.wave.ParticipantId;
+import org.waveprotocol.wave.util.logging.Log;
+
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -35,50 +82,6 @@
 import com.google.protobuf.RpcCallback;
 import com.google.protobuf.Service;
 import com.typesafe.config.Config;
-import org.apache.commons.lang.StringUtils;
-import org.atmosphere.cache.UUIDBroadcasterCache;
-import org.atmosphere.config.service.AtmosphereHandlerService;
-import org.atmosphere.cpr.*;
-import org.atmosphere.guice.AtmosphereGuiceServlet;
-import org.atmosphere.util.IOUtils;
-import org.eclipse.jetty.proxy.ProxyServlet;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.session.HashSessionManager;
-import org.eclipse.jetty.servlet.DefaultServlet;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.servlets.GzipFilter;
-import org.eclipse.jetty.util.resource.ResourceCollection;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.webapp.WebAppContext;
-import org.eclipse.jetty.websocket.servlet.*;
-import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolAuthenticate;
-import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolAuthenticationResult;
-import org.waveprotocol.box.server.authentication.SessionManager;
-import org.waveprotocol.box.server.executor.ExecutorAnnotations.ClientServerExecutor;
-import org.waveprotocol.box.server.persistence.file.FileUtils;
-import org.waveprotocol.box.server.rpc.atmosphere.AtmosphereChannel;
-import org.waveprotocol.box.server.rpc.atmosphere.AtmosphereClientInterceptor;
-import org.waveprotocol.box.server.util.NetUtils;
-import org.waveprotocol.box.stat.Timer;
-import org.waveprotocol.box.stat.Timing;
-import org.waveprotocol.wave.model.util.Pair;
-import org.waveprotocol.wave.model.wave.ParticipantId;
-import org.waveprotocol.wave.util.logging.Log;
-
-import javax.annotation.Nullable;
-import javax.servlet.DispatcherType;
-import javax.servlet.Filter;
-import javax.servlet.ServletContextListener;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpSession;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
 
 /**
  * ServerRpcProvider can provide instances of type Service over an incoming
@@ -146,32 +149,6 @@
     }
   }
 
-  static class AtmosphereConnection extends Connection {
-
-    private final AtmosphereChannel atmosphereChannel;
-
-    public AtmosphereConnection(ParticipantId loggedInUser, ServerRpcProvider provider) {
-      super(loggedInUser, provider);
-
-      atmosphereChannel = new AtmosphereChannel(this);
-      expectMessages(atmosphereChannel);
-
-    }
-
-    @Override
-    protected void sendMessage(int sequenceNo, Message message) {
-      atmosphereChannel.sendMessage(sequenceNo, message);
-    }
-
-    public AtmosphereChannel getAtmosphereChannel() {
-      return atmosphereChannel;
-    }
-
-
-  }
-
-
-
   static abstract class Connection implements ProtoCallback {
     private final Map<Integer, ServerRpcController> activeRpcs =
         new ConcurrentHashMap<>();
@@ -409,16 +386,6 @@
     // TODO(zamfi): fix to let messages span frames.
     wsholder.setInitParameter("bufferSize", "" + BUFFER_SIZE);
 
-    // Atmosphere framework. Replacement of Socket.IO
-    // See https://issues.apache.org/jira/browse/WAVE-405
-    ServletHolder atholder = addServlet("/atmosphere*", AtmosphereGuiceServlet.class);
-    // Enable guice. See
-    // https://github.com/Atmosphere/atmosphere/wiki/Configuring-Atmosphere%27s-Classes-Creation-and-Injection
-    atholder.setInitParameter("org.atmosphere.cpr.objectFactory",
-        "org.waveprotocol.box.server.rpc.atmosphere.GuiceAtmosphereFactory");
-    atholder.setAsyncSupported(true);
-    atholder.setInitOrder(0);
-
     // Serve the static content and GWT web client with the default servlet
     // (acts like a standard file-based web server).
     addServlet("/static/*", DefaultServlet.class);
@@ -566,178 +533,6 @@
   }
 
   /**
-   * Manange atmosphere connections and dispatch messages to
-   * wave channels.
-   *
-   * @author pablojan@gmail.com <Pablo Ojanguren>
-   *
-   */
-  @Singleton
-  @AtmosphereHandlerService(path = "/atmosphere",
-      interceptors = {AtmosphereClientInterceptor.class},
-      broadcasterCache = UUIDBroadcasterCache.class)
-  public static class WaveAtmosphereService implements AtmosphereHandler {
-
-
-    private static final Log LOG = Log.get(WaveAtmosphereService.class);
-
-    private static final String WAVE_CHANNEL_ATTRIBUTE = "WAVE_CHANNEL_ATTRIBUTE";
-    private static final String MSG_SEPARATOR = "|";
-    private static final String MSG_CHARSET = "UTF-8";
-
-    @Inject
-    public ServerRpcProvider provider;
-
-
-    @Override
-    public void onRequest(AtmosphereResource resource) throws IOException {
-
-      AtmosphereResourceSession resourceSession =
-          AtmosphereResourceSessionFactory.getDefault().getSession(resource);
-
-      AtmosphereChannel resourceChannel =
-          resourceSession.getAttribute(WAVE_CHANNEL_ATTRIBUTE, AtmosphereChannel.class);
-
-      if (resourceChannel == null) {
-
-        ParticipantId loggedInUser =
-            provider.sessionManager.getLoggedInUser(resource.getRequest().getSession(false));
-
-        AtmosphereConnection connection = new AtmosphereConnection(loggedInUser, provider);
-        resourceChannel = connection.getAtmosphereChannel();
-        resourceSession.setAttribute(WAVE_CHANNEL_ATTRIBUTE, resourceChannel);
-        resourceChannel.onConnect(resource);
-      }
-
-      resource.setBroadcaster(resourceChannel.getBroadcaster()); // on every
-                                                                 // request
-
-      if (resource.getRequest().getMethod().equalsIgnoreCase("GET")) {
-
-        resource.suspend();
-
-      }
-
-
-      if (resource.getRequest().getMethod().equalsIgnoreCase("POST")) {
-
-        StringBuilder b = IOUtils.readEntirely(resource);
-        resourceChannel.onMessage(b.toString());
-
-      }
-
-    }
-
-
-    @Override
-    public void onStateChange(AtmosphereResourceEvent event) throws IOException {
-
-
-      AtmosphereResponse response = event.getResource().getResponse();
-      AtmosphereResource resource = event.getResource();
-
-      if (event.isSuspended()) {
-
-        // Set content type before do response.getWriter()
-        // http://docs.oracle.com/javaee/5/api/javax/servlet/ServletResponse.html#setContentType(java.lang.String)
-        response.setContentType("text/plain; charset=UTF-8");
-        response.setCharacterEncoding("UTF-8");
-
-
-        if (event.getMessage().getClass().isArray()) {
-
-          LOG.fine("SEND MESSAGE ARRAY " + event.getMessage().toString());
-
-          List<Object> list = Collections.singletonList(event.getMessage());
-
-          response.getOutputStream().write(MSG_SEPARATOR.getBytes(MSG_CHARSET));
-          for (Object object : list) {
-            String message = (String) object;
-            message += MSG_SEPARATOR;
-            response.getOutputStream().write(message.getBytes(MSG_CHARSET));
-          }
-
-        } else if (event.getMessage() instanceof List) {
-
-          LOG.fine("SEND MESSAGE LIST " + event.getMessage().toString());
-
-          @SuppressWarnings("unchecked")
-          List<Object> list = List.class.cast(event.getMessage());
-
-          response.getOutputStream().write(MSG_SEPARATOR.getBytes(MSG_CHARSET));
-          for (Object object : list) {
-            String message = (String) object;
-            message += MSG_SEPARATOR;
-            response.getOutputStream().write(message.getBytes(MSG_CHARSET));
-          }
-
-        } else if (event.getMessage() instanceof String) {
-
-          LOG.fine("SEND MESSAGE " + event.getMessage().toString());
-
-          String message = (String) event.getMessage();
-          response.getOutputStream().write(message.getBytes(MSG_CHARSET));
-        }
-
-
-
-        try {
-
-          response.flushBuffer();
-
-          switch (resource.transport()) {
-            case JSONP:
-            case LONG_POLLING:
-              event.getResource().resume();
-              break;
-            case WEBSOCKET:
-            case STREAMING:
-            case SSE:
-              response.getOutputStream().flush();
-              break;
-            default:
-              LOG.info("Unknown transport");
-              break;
-          }
-        } catch (IOException e) {
-          LOG.info("Error resuming resource response", e);
-        }
-
-
-      } else if (event.isResuming()) {
-
-        LOG.fine("RESUMING");
-
-      } else if (event.isResumedOnTimeout()) {
-
-        LOG.fine("RESUMED ON TIMEOUT");
-
-      } else if (event.isClosedByApplication() || event.isClosedByClient()) {
-
-        LOG.fine("CONNECTION CLOSED");
-
-        AtmosphereResourceSession resourceSession =
-            AtmosphereResourceSessionFactory.getDefault().getSession(resource);
-
-        AtmosphereChannel resourceChannel =
-            resourceSession.getAttribute(WAVE_CHANNEL_ATTRIBUTE, AtmosphereChannel.class);
-
-        if (resourceChannel != null) {
-          resourceChannel.onDisconnect();
-        }
-      }
-    }
-
-    @Override
-    public void destroy() {
-      // Nothing to do
-
-    }
-
-
-  }
-
-  /**
    * Returns the socket the WebSocket server is listening on.
    */
   public SocketAddress getWebSocketAddress() {
diff --git a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereChannel.java b/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereChannel.java
deleted file mode 100644
index 4bc9adb..0000000
--- a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereChannel.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.waveprotocol.box.server.rpc.atmosphere;
-
-
-import org.atmosphere.cpr.AtmosphereResource;
-import org.atmosphere.cpr.Broadcaster;
-import org.atmosphere.cpr.BroadcasterFactory;
-import org.waveprotocol.box.server.rpc.ProtoCallback;
-import org.waveprotocol.box.server.rpc.WebSocketChannel;
-import org.waveprotocol.wave.util.logging.Log;
-
-import java.io.IOException;
-
-/**
- * An atmosphere wrapper for the WebSocketChannel type.
- *
- * @author pablojan@gmail.com (Pablo Ojanguren)
- */
-public class AtmosphereChannel extends WebSocketChannel  {
-
-
-  private static final Log LOG = Log.get(AtmosphereChannel.class);
-
-  /* The object needed to send messages out */
-  private Broadcaster broadcaster;
-
-
-
-  /**
-   * Creates a new AtmosphereChannel using the callback for incoming messages.
-   *
-   * @param callback A ProtoCallback instance called with incoming messages.
-   */
-  public AtmosphereChannel(ProtoCallback callback) {
-    super(callback);
-    broadcaster = BroadcasterFactory.getDefault().get();
-
-  }
-
-  /**
-   * A new resource connection has been associated with
-   * this channel
-   * @param resource the Atmosphere resource object
-   */
-  public void onConnect(AtmosphereResource resource) {
-
-    // Create a new broadcaster to publish to this resource
-    broadcaster.addAtmosphereResource(resource);
-  }
-
-
-  public Broadcaster getBroadcaster() {
-    return broadcaster;
-  }
-
-  /**
-   * The atmosphere resource has received a new post message
-   * @param message the message
-   */
-  public void onMessage(String message) {
-
-    handleMessageString(message);
-  }
-
-  /**
-   * The atmosphere resource has been closed
-   */
-  public void onDisconnect() {
-
-    broadcaster = null;
-  }
-
-
-
-  /**
-   * Send the given data String
-   *
-   * @param data
-   * @throws IOException
-   */
-  @Override
-  protected void sendMessageString(String data) throws IOException {
-
-      if (broadcaster == null || broadcaster.isDestroyed()) {
-        // Just drop the message. It's rude to throw an exception since the
-        // caller had no way of knowing.
-        LOG.warning("Atmosphere Channel is not connected");
-      } else {
-
-       LOG.fine("BROADCAST "+data);
-       broadcaster.broadcast(data);
-    }
-  }
-
-
-
-
-}
diff --git a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereClientInterceptor.java b/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereClientInterceptor.java
deleted file mode 100644
index 12468d3..0000000
--- a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/AtmosphereClientInterceptor.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.waveprotocol.box.server.rpc.atmosphere;
-
-
-
-import com.google.common.io.ByteStreams;
-
-import org.atmosphere.config.service.AtmosphereInterceptorService;
-import org.atmosphere.cpr.Action;
-import org.atmosphere.cpr.AtmosphereConfig;
-import org.atmosphere.cpr.AtmosphereInterceptor;
-import org.atmosphere.cpr.AtmosphereRequest;
-import org.atmosphere.cpr.AtmosphereResource;
-import org.waveprotocol.wave.util.logging.Log;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
- /**
- * Serve atmosphere.js file to GWT clients This class allows to serve the
- * Atmosphere Javascript client from the same /atmosphere servlet path which is
- * used to process any Atmosphere request instead of place it on the /static
- * path. In addition, the Javascript file is put together with the rest of
- * Atmosphere related source code, during the build process as any other third
- * party dependency.
- * 
- * 
- * @author pablojan@gmail.com (Pablo Ojanguren)
- */
-  @AtmosphereInterceptorService
-  public class AtmosphereClientInterceptor implements AtmosphereInterceptor  {
-
-    private static final Log LOG = Log.get(AtmosphereClientInterceptor.class);
-
-    @Override
-    public void configure(AtmosphereConfig config) {
-        // Nothing to do
-    }
-
-    @Override
-    public Action inspect(AtmosphereResource resource) {
-
-      AtmosphereRequest request = resource.getRequest();
-
-      try {
-        // Find the first context parameter
-        String path = request.getPathInfo();
-
-        if (path == null || path.isEmpty())
-         return Action.CONTINUE;
-
-        if (path.startsWith("/")) {
-          path = path.substring(1);
-        }
-        String[] parts = path.split("/");
-
-        // Serve the file
-        if (parts.length > 0 && "GET".equals(resource.getRequest().getMethod()) && "atmosphere.js".equals(parts[0])) {
-          resource.getResponse().setContentType("text/javascript");
-          InputStream is =
-              this.getClass().getClassLoader()
-                  .getResourceAsStream("org/waveprotocol/box/server/rpc/atmosphere/atmosphere.js");
-          OutputStream os = resource.getResponse().getOutputStream();
-          ByteStreams.copy(is, os);
-          return Action.CANCELLED;
-
-        }
-
-
-      } catch (IOException e) {
-        LOG.severe("Error sending atmosphere.js",e);
-      }
-
-
-      return Action.CONTINUE;
-    }
-
-
-    @Override
-    public void postInspect(AtmosphereResource resource) {
-      // Nothing to do
-    }
-
-  }
diff --git a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/GuiceAtmosphereFactory.java b/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/GuiceAtmosphereFactory.java
deleted file mode 100644
index 3611caf..0000000
--- a/wave/src/main/java/org/waveprotocol/box/server/rpc/atmosphere/GuiceAtmosphereFactory.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.waveprotocol.box.server.rpc.atmosphere;
-
-import com.google.inject.Injector;
-
-import org.atmosphere.cpr.AtmosphereFramework;
-import org.atmosphere.cpr.AtmosphereObjectFactory;
-import org.waveprotocol.wave.util.logging.Log;
-
-/**
- * Custom factory to use wave's guice injector in Atmosphere
- *
- * @author pablojan@gmail.com (Pablo Ojanguren)
- *
- */
-public class GuiceAtmosphereFactory implements AtmosphereObjectFactory {
-
-  private static final Log LOG = Log.get(GuiceAtmosphereFactory.class);
-
-  private static Injector injector;
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public <T, U extends T> U newClassInstance(AtmosphereFramework framework, Class<T> classType, Class<U> classToInstantiate) throws InstantiationException, IllegalAccessException {
-      initInjector(framework);
-
-
-      if (injector == null) {
-          return classToInstantiate.newInstance();
-      } else {
-          return injector.getInstance(classToInstantiate);
-      }
-  }
-
-  public String toString() {
-      return "Guice ObjectFactory";
-  }
-
-  private void initInjector(AtmosphereFramework framework) {
-      if (injector == null) {
-          com.google.inject.Injector servletInjector = (com.google.inject.Injector)
- framework.getServletContext().getAttribute(
-              com.google.inject.Injector.class.getName());
-
-          if (servletInjector != null) {
-              injector = servletInjector;
-              LOG.fine("Existing injector found to create Atmosphere instances");
-          } else {
-              LOG.fine("Not injector not found to create Atmosphere instances");
-          }
-      }
-  }
-}
diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveSocketFactory.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveSocketFactory.java
index d79ce4e..20d2bce 100644
--- a/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveSocketFactory.java
+++ b/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveSocketFactory.java
@@ -22,14 +22,9 @@
 import com.google.gwt.websockets.client.WebSocket;
 import com.google.gwt.websockets.client.WebSocketCallback;
 
-import org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnection;
-import org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionImpl;
-import org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionListener;
-
 
 /**
- * Factory to create proxy wrappers around either {@link com.google.gwt.websockets.client.WebSocket}
- * or {@link org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnection}.
+ * Factory to create proxy wrappers for {@link com.google.gwt.websockets.client.WebSocket}
  *
  * @author tad.glines@gmail.com (Tad Glines)
  */
@@ -37,52 +32,10 @@
 
   /**
    * Create a WaveSocket instance that wraps a concrete socket implementation.
-   * If useWebSocketAlt is true an instance of {@link org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnection}
-   * is wrapped, otherwise an instance of {@link com.google.gwt.websockets.client.WebSocket} is
-   * wrapped.
    */
-  public static WaveSocket create(boolean useWebSocketAlt, final String urlBase,
+  public static WaveSocket create(final String urlBase,
       final WaveSocket.WaveSocketCallback callback) {
-    if (useWebSocketAlt) {
-      return new WaveSocket() {
 
-        private final AtmosphereConnection socket
-        = new AtmosphereConnectionImpl(new AtmosphereConnectionListener() {
-
-          @Override
-          public void onConnect() {
-            callback.onConnect();
-          }
-
-          @Override
-          public void onDisconnect() {
-            callback.onDisconnect();
-          }
-
-          @Override
-          public void onMessage(String message) {
-            callback.onMessage(message);
-          }}, urlBase);
-
-        @Override
-        public void connect() {
-          socket.connect();
-
-        }
-
-        @Override
-        public void disconnect() {
-          socket.close();
-        }
-
-        @Override
-        public void sendMessage(String message) {
-              socket.sendMessage(message);
-        }
-
-        };
-
-    } else {
       return new WaveSocket() {
         final WebSocket socket = new WebSocket(new WebSocketCallback() {
           @Override
@@ -116,6 +69,5 @@
           socket.send(message);
         }
       };
-    }
   }
 }
diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveWebSocketClient.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveWebSocketClient.java
index 167ea94..98350a3 100644
--- a/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveWebSocketClient.java
+++ b/wave/src/main/java/org/waveprotocol/box/webclient/client/WaveWebSocketClient.java
@@ -114,11 +114,10 @@
   private final RepeatingCommand reconnectCommand = new RepeatingCommand() {
     @Override
     public boolean execute() {
-      if (!connectedAtLeastOnce && !websocketNotAvailable && connectTry > MAX_INITIAL_FAILURES) {
-        // Let's try to use websocket alternative, seems that websocket it's not working
-        // (we are under a proxy or similar)
-        socket = WaveSocketFactory.create(true, urlBase, WaveWebSocketClient.this);
+      if (connectTry > MAX_INITIAL_FAILURES) {
+    	  return false;
       }
+      
       connectTry++;
       if (connected == ConnectState.DISCONNECTED) {
         LOG.info("Attemping to reconnect");
@@ -128,16 +127,19 @@
       return true;
     }
   };
-  private final boolean websocketNotAvailable;
+
   private boolean connectedAtLeastOnce = false;
   private long connectTry = 0;
   private final String urlBase;
 
   public WaveWebSocketClient(boolean websocketNotAvailable, String urlBase) {
-    this.websocketNotAvailable = websocketNotAvailable;
     this.urlBase = urlBase;
     submitRequestCallbacks = CollectionUtils.createIntMap();
-    socket = WaveSocketFactory.create(websocketNotAvailable, urlBase, this);
+    if (websocketNotAvailable) {
+    	ClientEvents.get().fireEvent(new NetworkStatusEvent(ConnectionStatus.NEVER_CONNECTED));
+    	throw new RuntimeException("Websocket is not available");
+    }
+    socket = WaveSocketFactory.create(urlBase, this);
   }
 
   /**
diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnection.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnection.java
deleted file mode 100644
index 29b1f24..0000000
--- a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnection.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.waveprotocol.box.webclient.client.atmosphere;
-
-/**
- * The atmosphere connection interface for wrapping the javascript
- * client in GWT
- *
- * @author pablojan@gmail.com (Pablo Ojanguren)
- *
- */
-public interface AtmosphereConnection {
-
-
-  /**
-   * Initiate a connection attempt.
-   *
-   */
-  void connect();
-
-  /**
-   * Initiate an orderly close of the connection.
-   *
-   */
-  void close();
-
-
-  /**
-   * Send a message.
-   *
-   * @param message
-   */
-  void sendMessage(String message);
-
-
-}
\ No newline at end of file
diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionImpl.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionImpl.java
deleted file mode 100644
index c405f18..0000000
--- a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionImpl.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.waveprotocol.box.webclient.client.atmosphere;
-
-import com.google.gwt.core.client.Callback;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.ScriptInjector;
-
-/**
- * The wrapper implementation of the atmosphere javascript client.
- *
- * https://github.com/Atmosphere/atmosphere/wiki/jQuery.atmosphere.js-atmosphere
- * .js-API
- *
- * More info about transports
- * https://github.com/Atmosphere/atmosphere/wiki/Supported
- * -WebServers-and-Browsers
- *
- * It tries to use Server-Sent Events first and fallback transport to
- * long-polling. We ignore Websockets by now because they are the default
- * transport on WiAB and atmosphere is the fallback.
- *
- * http://stackoverflow.com/questions/9397528/server-sent-events-vs-polling
- *
- *
- * @author pablojan@gmail.com (Pablo Ojanguren)
- *
- */
-public class AtmosphereConnectionImpl implements AtmosphereConnection {
-
-
-      private static final class AtmosphereSocket extends JavaScriptObject {
-        public static native AtmosphereSocket create(AtmosphereConnectionImpl impl, String urlBase) /*-{
-
-      var client = $wnd.atmosphere;
-
-                var atsocket = {
-                    request: null,
-                    socket: null };
-
-                var connectionUrl = window.location.protocol + "//" +  $wnd.__websocket_address + "/";
-
-                connectionUrl += 'atmosphere';
-
-                //console.log("Connection URL is "+urlBase);
-                atsocket.request = new client.AtmosphereRequest();
-                atsocket.request.url = connectionUrl;
-                atsocket.request.contenType = 'text/plain;charset=UTF-8';
-                atsocket.request.transport = 'sse';
-                atsocket.request.fallbackTransport = 'long-polling';
-
-                atsocket.request.onOpen = $entry(function() {
-                    impl.@org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionImpl::onConnect()();
-                });
-
-                atsocket.request.onMessage =  $entry(function(response) {
-
-                  var r = response.responseBody;
-
-                  if (r.indexOf('|') == 0) {
-
-                      while (r.indexOf('|') == 0 && r.length > 1) {
-
-                        r = r.substring(1);
-                        var marker = r.indexOf('}|');
-                        impl.@org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionImpl::onMessage(Ljava/lang/String;)(r.substring(0, marker+1));
-                        r = r.substring(marker+1);
-
-                     }
-
-                  }
-                  else {
-
-                    impl.@org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionImpl::onMessage(Ljava/lang/String;)(r);
-
-                  }
-
-                });
-
-                atsocket.request.onClose = $entry(function(response) {
-
-                   client.util.info("Connection closed");
-
-                   impl.@org.waveprotocol.box.webclient.client.atmosphere.AtmosphereConnectionImpl::onDisconnect(Ljava/lang/String;)(response);
-                });
-
-
-
-                atsocket.request.onTransportFailure = function(errorMsg, request) {
-
-                      client.util.info(errorMsg);
-
-                  };
-
-
-                atsocket.request.onReconnect = function(request, response) {
-
-                      client.util.info("Reconnected to the server");
-
-                  };
-
-                  atsocket.request.onError = function(response) {
-
-                      client.util.info("Unexpected Error");
-
-                  };
-
-
-                return atsocket;
-
-
-        }-*/;
-
-        protected AtmosphereSocket() {
-    }
-
-
-    public native void close() /*-{
-			this.socket.unsubscribe();
-    }-*/;
-
-    public native AtmosphereSocket connect() /*-{
-			this.socket = $wnd.atmosphere.subscribe(this.request);
-
-    }-*/;
-
-    public native void send(String data) /*-{
-			this.socket.push(data);
-    }-*/;
-    }
-
-
-    private final AtmosphereConnectionListener listener;
-    private String urlBase;
-    private AtmosphereConnectionState state;
-    private AtmosphereSocket socket = null;
-
-    public AtmosphereConnectionImpl(AtmosphereConnectionListener listener,
-               String urlBase) {
-        this.listener = listener;
-        this.urlBase = urlBase;
-
-    }
-
-
-    @Override
-    public void connect() {
-        if (socket == null) {
-
-                ScriptInjector.fromUrl("/atmosphere/atmosphere.js").setCallback(
-                        new Callback<Void, Exception>() {
-                                public void onFailure(Exception reason) {
-                                        throw new IllegalStateException("atmosphere.js load failed!");
-                                }
-                                public void onSuccess(Void result) {
-
-                                        socket = AtmosphereSocket.create(AtmosphereConnectionImpl.this, urlBase);
-                                        socket.connect();
-                                }
-                        }).setWindow(ScriptInjector.TOP_WINDOW).inject();
-        } else {
-
-
-          if (AtmosphereConnectionState.CLOSED.equals(this.state))
-            socket.connect();
-
-        }
-    }
-
-    @Override
-    public void close() {
-        if (!AtmosphereConnectionState.CLOSED.equals(this.state))
-                socket.close();
-
-    }
-
-
-    @Override
-    public void sendMessage(String message) {
-    this.state = AtmosphereConnectionState.MESSAGE_PUBLISHED;
-        socket.send(message);
-    }
-
-
-
-    @SuppressWarnings("unused")
-    private void onConnect() {
-    this.state = AtmosphereConnectionState.OPENED;
-        listener.onConnect();
-    }
-
-  /**
-   * This method is called when an Atmosphere onClose event happens:
-   *
-   * when an error occurs. when the server or a proxy closes the connection.
-   * when an expected exception occurs. when the specified transport is not
-   * supported or fail to connect.
-   *
-   * @param response
-   *
-   */
-    @SuppressWarnings("unused")
-    private void onDisconnect(String response) {
-      this.state = AtmosphereConnectionState.CLOSED;
-      listener.onDisconnect();
-    }
-
-    @SuppressWarnings("unused")
-    private void onMessage(String message) {
-    this.state = AtmosphereConnectionState.MESSAGE_RECEIVED;
-      listener.onMessage(message);
-    }
-
-
-}
diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionListener.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionListener.java
deleted file mode 100644
index aff7bfd..0000000
--- a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionListener.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.waveprotocol.box.webclient.client.atmosphere;
-
-/**
- * The listener interface for the atmosphere client wrapper.
- *
- * @author pablojan@gmail.com (Pablo Ojanguren)
- *
- */
-public interface AtmosphereConnectionListener {
-
-  /**
-   * Called when a successful connection with server is performed
-   */
-  void onConnect();
-
-  /**
-   * Called when connection is closed properly or by error
-   */
-  void onDisconnect();
-
-  /**
-   * Called when a new message is received from the server
-   * @param message
-   */
-  void onMessage(String message);
-
-
-
-}
diff --git a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionState.java b/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionState.java
deleted file mode 100644
index a6b3c94..0000000
--- a/wave/src/main/java/org/waveprotocol/box/webclient/client/atmosphere/AtmosphereConnectionState.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.waveprotocol.box.webclient.client.atmosphere;
-
-/**
- * Connection state definition inspired by former SocketIO/WebSocket
- * implementation
- *
- * @author pablojan@gmail.com (Pablo Ojanguren)
- *
- */
-public enum AtmosphereConnectionState {
-
-  MESSAGE_RECEIVED("messageReceived"),
- MESSAGE_PUBLISHED("messagePublished"), OPENED("opened"),
-  CLOSED("closed"), UNKNOWN("unknown");
-
-    private String value;
-    private AtmosphereConnectionState(String v) { this.value = v; }
-    public String value() { return value; }
-
-    public static AtmosphereConnectionState fromString(String val) {
-
-    if (val.equals("messageReceived")) {
-      return MESSAGE_RECEIVED;
-    } else if (val.equals("messagePublished")) {
-      return MESSAGE_PUBLISHED;
-    } else if (val.equals("opened")) {
-      return OPENED;
-    } else if (val.equals("closed")) {
-      return CLOSED;
-    }
-
-        return UNKNOWN;
-    }
-}