WL.ErrorInfo = WL.Class( Object, function( base, type )
{
	this.constructor = function( code, text )
	{
		this.code = code || 0;
		this.text = text || "";
	}
	
	type.UnspecifiedError = 1;
	type.InternalError = 2;
	type.Timeout = 3;
	type.Logout = 4;
	type.ScriptError = 5;
	type.XmlError = 6;

	this.read = function( reader )
	{
		this.code = reader.readInt( "code" );
		this.text = reader.readString( "message" );
	}
	
	this.toString = function() { return this.text; }
} );

WL.CallbackData = {
	KeyInputID : "__SCRIPTCALLBACKID",
	KeyStatus : "__SCRIPTCALLBACKSTATUS",
	StatusOK : "200",
	StatusNotFound : "404",		
	StatusInternalError : "500",
	StatusNotImplemented : "501",
	StatusLogout : "503"
};

////////////////////////////////////////////////////
WL.ServerAPI = {};
WL.ServerAPI.Request = WL.Class( Object, function()
{
	this.constructor = function( guid, method )
	{
		this.body = new WL.Objects.XmlWriter();	
		this.body.writeStartElement( "XmlRpcRequest" );
		this.body.writeAttributeString( "iid", guid );
		this.body.writeAttributeString( "method", method );
	}
	this.toString = function()
	{
		this.body.writeEndElement();	
		return this.body.toString();
	}
} );

WL.ServerAPI.MultiRequest = WL.Class( WL.ServerAPI.Request, function( base )
{
	this.constructor = function()
	{
		base.constructor.call( this, WL.Guids.Api.WebGeneral, "InvokeRequests" );
		this.requests = [];
	}

	this.addRequest = function( request ) { this.requests.push( request ); }
	
	this.toString = function()
	{
		for( var i = 0; i < this.requests.length; ++i )
			this.body.write( this.requests[i] );
		this.body.writeEndElement();
		return this.body.toString();
	}
} );

WL.XmlCallback = WL.Class( Object, function()
{
	this.constructor = function()
	{
		this.callbackList = [];
		this.re = new RegExp( "\\x2B", "g" );	
		this.fix = 0;
	}

	this.initCallbackPage = function( pageUrl )
	{
		this.pageUrl = pageUrl;
	}
	
	this.getPostData = function()
	{
		var formPostData = "";
		var theForm = document.forms[0];
		var count = theForm.elements.length;
		var element;
	    
		for( var i = 0; i < count; i++ )
		{
			element = theForm.elements[i];
			
			if( element.tagName.toUpperCase() == "INPUT" && 
				element.type != "button" && 
				element.type != "submit" && 
				element.type != "reset" ) 
			{
				formPostData += element.name + "=" + element.value.replace( this.re, "%2B" ) + "&";
			}
			else if( element.tagName.toUpperCase() == "SELECT" ) 
			{				
				selectCount = element.length;				
				for( var j = 0; j < selectCount; j++ ) 
				{				
					selectChild = element[j];					
					if( ( selectChild.tagName.toUpperCase() == "OPTION" ) && 
						( selectChild.selected == true ) ) 
					{
						formPostData += element.name + "=" + selectChild.value.replace( this.re, "%2B" ) + "&";                
					}                
				}
			}
		}
		return formPostData;
	}
	
	var __selectSingleNode;
if( WL.browser.ie )
{	
	__selectSingleNode = function( tagName ) { return this.selectSingleNode( tagName ); }
}
else // if( WL.browser.ie )
{
	__selectSingleNode = function( tagName )
	{
		if( tagName == "//" ) return this.firstChild;
		for( var i = 0; i < this.childNodes.length; ++i )
			if( this.childNodes[i].tagName == tagName ) return this.childNodes[i];
		return null;
	}
} // else if( WL.browser.ie )
	
	var getRequestObject = function()
	{
		if( window.XMLHttpRequest )	return new XMLHttpRequest();	
		if( window.ActiveXObject )
		{
			try { return new ActiveXObject("Msxml2.XMLHTTP"); }
			catch(e) { return new ActiveXObject("Microsoft.XMLHTTP"); }
		}
		return null;
	}
	
	this.doSyncCallback = function( pageUrl, eventArgument ) 
	{
		try
		{
			var xmlRequest = getRequestObject();
			if( xmlRequest != null )
			{
				if( eventArgument )
				{
					xmlRequest.open( "POST", pageUrl, false );
					xmlRequest.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
					xmlRequest.send( eventArgument );
				}
				else
				{
					xmlRequest.open( "GET", pageUrl, false );
					xmlRequest.send(null);
				}
				
				var callbackObject = new Object();
					callbackObject.xmlRequest	 = xmlRequest;
					callbackObject.eventArgument = eventArgument;
				return callbackObject;
				/*
				var errorInfo	 = null;		
				var xmlResponse	 = xmlRequest.responseXML;
				var textResponse = xmlRequest.responseText;
				var cbStatus	 = xmlRequest.getResponseHeader( WL.CallbackData.KeyStatus );

				if( cbStatus == WL.CallbackData.StatusLogout )				 
				{
					errorInfo = new WL.ErrorInfo( WL.ErrorInfo.Logout, "Logout" );			
					if( window.logout != null ) { window.logout(); return null;	}
				}
				else if( xmlRequest.status != 200 )	errorInfo = new WL.ErrorInfo( WL.ErrorInfo.InternalError, xmlRequest.statusText );
				else if( cbStatus == "" ) errorInfo = new WL.ErrorInfo( WL.ErrorInfo.InternalError, "No server response" );
				else if( cbStatus != WL.CallbackData.StatusOK )	errorInfo = new WL.ErrorInfo( WL.ErrorInfo.InternalError, textResponse );
				else if( xmlResponse.parseError != null && xmlResponse.parseError.errorCode != 0 && textResponse != "" )						
					errorInfo = new WL.ErrorInfo( WL.ErrorInfo.XmlError, xmlResponse.parseError.reason );
				
				xmlRequest = null;
							
				if( errorInfo != null ) 
				{
					if( errorCallback != null ) errorCallback( errorInfo );
					WL.Utils.assert( true, errorInfo );
					return null;
				}		
				var node = __selectSingleNode.call( xmlResponse, "//" );
				return node ? new WL.Objects.XmlReader( node ) : null;*/
			}
		}
		catch(e){ WL.alert( e.message ); }
	}
		
	this.doAsyncCallback = function( pageUrl, eventArgument, callback, options /*context, eventCallback, errorCallback, hidden, timeout*/ ) 
	{
		try
		{
			if( !options ) options = {};
		
			var xmlRequest = getRequestObject();
			if( xmlRequest != null )
			{		
				xmlRequest.onreadystatechange = onAsyncCallbackComplete;

				var callbackObject = new Object();
					callbackObject.xmlRequest	 = xmlRequest;
					callbackObject.eventArgument = eventArgument;
					callbackObject.callback		 = callback;
				//	callbackObject.context		 = context;
				//	callbackObject.eventCallback = eventCallback;		
				//	callbackObject.errorCallback = errorCallback;
					callbackObject.hidden		 = options.hidden ? true : false;
					callbackObject.timeout		 = options.timeout || WL.TimeOut;					
				
				this.addCallback( callbackObject );
				
				if( eventArgument )
				{
					xmlRequest.open( "POST", pageUrl, true );
					xmlRequest.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
					xmlRequest.send( eventArgument.replace( this.re, "%2B" ) );
				}
				else
				{
					xmlRequest.open( "GET", pageUrl, true );
					xmlRequest.send(null);
				}
			}
		}
		catch(e){ WL.alert( e.message ); }
	}
	
	this.addCallback = function( cb ) 
	{
		cb.executed = false;
		this.callbackList.push( cb );
		
		this.updateWindowStatus();
		
		if( cb.timeout == -1 ) return;
		cb.timeoutCookie = window.setTimeout( addCallback_timeout.bind( this, cb ), cb.timeout );
	}
	var addCallback_timeout = function( cb )
	{
		for( var i = 0; i < this.callbackList.length; ++i )
			if( this.callbackList[i] == cb )
			{
				var error = new WL.ErrorInfo( WL.ErrorInfo.Timeout, String.format( "Timeout {0} seconds", cb.timeout / 1000 ) );
				
				this.callbackList[i] = null;
				this.callbackList.splice( i, 1 );
									
				if( cb.errorCallback != null ) 
					cb.errorCallback.call( cb.context, error );
					
				this.updateWindowStatus();
				
				WL.alert( error.text );				
				return;
			}
	}
	
	var onAsyncCallbackComplete = function() 
	{
		if( window.xmlCallback == null ) return;

		var list = window.xmlCallback.callbackList;
		for( var i = 0; i < list.length; i++ )
		{
			var cbObject = list[i];			
			if( cbObject.xmlRequest.readyState == 4 &&
				cbObject.executed == false ) 
			{
				cbObject.executed = true;
				window.clearTimeout( cbObject.timeoutCookie );
							
				list.removeAt( i-- );
				window.xmlCallback.updateWindowStatus();
				
				if( typeof(cbObject.callback)=="function" )
					cbObject.callback( cbObject );
			
				cbObject.xmlRequest = null;
				cbObject = null;
			}
		}
	}
	
	this.doWebServerComplete = function( cbObject ) 
	{
		var xmlResponse	 = cbObject.xmlRequest.responseXML;
		var textResponse = cbObject.xmlRequest.responseText;
		var cbStatus	 = cbObject.xmlRequest.getResponseHeader( WL.CallbackData.KeyStatus );

		var errorInfo = null;
		if( cbStatus == WL.CallbackData.StatusLogout )				 
		{
			errorInfo = new WL.ErrorInfo( WL.ErrorInfo.Logout, "Logout" );
			if( window.logout != null )
			{
				window.logout();
				return;	
			}
		}
		else if( cbObject.xmlRequest.status != 200 ) errorInfo = new WL.ErrorInfo( WL.ErrorInfo.InternalError, String.format( "Status: {0}\nText: {1}", cbObject.xmlRequest.status, cbObject.xmlRequest.statusText ) );
		else if( cbStatus == "" ) errorInfo = new WL.ErrorInfo( WL.ErrorInfo.InternalError, "No server response" );
		else if( cbStatus != WL.CallbackData.StatusOK ) errorInfo = new WL.ErrorInfo( WL.ErrorInfo.InternalError, textResponse );
		else if( xmlResponse.parseError != null && xmlResponse.parseError.errorCode != 0 && textResponse != "" )
			errorInfo = new WL.ErrorInfo( WL.ErrorInfo.XmlError, "XmlResponse parsing", xmlResponse.parseError.reason );
		else
		{
			var rn = __selectSingleNode.call( xmlResponse, "//" );
			if( rn != null && rn.getAttribute("isError") == "1" )
			{
				errorInfo = new WL.ErrorInfo( WL.ErrorInfo.UnspecifiedError, "Unspecified Server Error" );
				var errorNode = __selectSingleNode.call( rn, "error" );
				if( errorNode != null )
				{
					var enc = __selectSingleNode.call( errorNode, "code" );
					var enm = __selectSingleNode.call( errorNode, "message" );
					errorInfo.code = Number( typeof(enc.text)!="undefined" ? enc.text : enc.textContent );
					errorInfo.text = typeof(enm.text)!="undefined" ? enm.text : enm.textContent;
				}
			}
		}
		
		if( errorInfo != null ) 
		{
			if( cbObject.errorCallback != null ) 
				cbObject.errorCallback.call( cbObject.context, errorInfo );
			else
				WL.Utils.assert( true, errorInfo.toString() );
		}
		else
		{
			if( cbObject.eventCallback != null ) 
			{
				var n = __selectSingleNode.call( xmlResponse, "//" );
				cbObject.eventCallback.call( cbObject.context, n ? new WL.Objects.XmlReader(n) : null );
			}
		}
	}
	
	this.doAsyncCall = function( pageUrl, eventArgument ) 
	{
		try
		{
			var xmlRequest = getRequestObject();
			if( xmlRequest != null )
			{
				xmlRequest.open( "POST", pageUrl, true );
				xmlRequest.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
				xmlRequest.send( eventArgument.replace( this.re, "%2B" ) );	
			}
		}
		catch(e){ WL.alert( e.message ); }
	}
	
	////////////////////////
	this.doCallback = function( eventTarget, eventArgument, context, eventCallback, errorCallback, hidden )
	{
		var eventArgument =	this.getPostData() + 
							WL.CallbackData.KeyInputID + 
							eventTarget + "&" + 
							eventArgument;
						
		this.doAsyncCallback( this.pageUrl, eventArgument, function( cbObject )
		{
			cbObject.eventCallback = eventCallback;
			cbObject.errorCallback = errorCallback;
			cbObject.context = context;
			window.xmlCallback.doWebServerComplete( cbObject );
		}, {hidden:hidden,timeout:null} );//   context, eventCallback, errorCallback, hidden );
	}
		
	var webCallStack = [];
	this.doWebRequest = function( request, context, eventHandler, errorHandler, hidden )
	{
		webCallStack.push( {r:request,c:context,h:eventHandler,e:errorHandler,hide:hidden} );	
		if( this._webcallcookie ) window.clearTimeout( this._webcallcookie );
		this._webcallcookie = window.setTimeout( invokeWebStack, 0 );
	}
	
	this.doWebSyncRequest = function( request, errorHandler )
	{
		var eventArgument = "request=" + encodeURIComponent( request.toString() );
		
		var cbObject = this.doSyncCallback( window.baseUrl + "/webcall.ashx", eventArgument );
		var returnReader = null;
		cbObject.context = this;
		cbObject.eventCallback = function( reader ) { returnReader = reader; };
		cbObject.errorCallback = errorHandler;
		window.xmlCallback.doWebServerComplete( cbObject );
		return returnReader;
	}
	
	var lateRequests = [];
	this.doLateRequest = function( request, context, key, eventHandler, errorHandler, hidden )
	{
		lateRequests.removeIf( function(it) { return it.k == key; } );
		lateRequests.push( {k:key,r:request,c:context,h:eventHandler,e:errorHandler,hide:hidden} );	
	}
	
if( WL.UseAsyncBigRequest )
{
	this.doBigRequest = function( request, context, eventHandler, endRequest, errorHandler )
	{
		var req = new WL.ServerAPI.Request( WL.Guids.Api.WebGeneral, "Big" );		
			req.body.write( request );
			
		var handler = function( reader )
		{
			var cookie = reader.readInt( "cookie", -1 );
			var bigRequest = null;
			if( cookie != -1 )
			{
				bigRequest = new WL.BigRequest( cookie );
				bigRequest.wait( endRequest, errorHandler );
			}
				
			if( eventHandler ) eventHandler.call( context, {error:cookie==-1, br:bigRequest} );			
		}
		
		webCallStack.push( {r:req,c:context,h:handler,e:errorHandler,big:true,hide:false} );	
		if( this._webcallcookie ) window.clearTimeout( this._webcallcookie );
		this._webcallcookie = window.setTimeout( invokeWebStack, 0 );
	}
	
	this.getBigRequestCount = function()
	{
		var c=0;
		for(var i=0;i<webCallStack.length;++i)if(webCallStack[i].big)c++;
		return c;
	}
}
else // if( WL.UseAsyncBigRequest )
{
	this.doBigRequest = function( request, context, eventHandler, endRequest, errorHandler )
	{
		webCallStack.push( {r:request,c:context,h:eventHandler,e:errorHandler,big:true,hide:false} );	
		if( this._webcallcookie ) window.clearTimeout( this._webcallcookie );
		this._webcallcookie = window.setTimeout( invokeWebStack, 0 );
	}
	
	this.getBigRequestCount = function() { return 0; }
} // else if( WL.UseAsyncBigRequest )
	
	var invokeWebStack = function()
	{
		if( webCallStack.length == 1 && lateRequests.length == 0 )
		{
			var it = webCallStack[0];
			window.xmlCallback.doAsyncCallback( window.baseUrl + "/webcall.ashx", "request=" + encodeURIComponent( it.r.toString() ), function( cbObject )
				{
					cbObject.eventCallback = it.h;
					cbObject.errorCallback = it.e;
					cbObject.context = it.c;
					window.xmlCallback.doWebServerComplete( cbObject );
				}, {hidden:it.hide,timeout:null} ); // it.c, it.h, it.e, it.hide );
		}
		else
		{	
			var list	= new Array();
			var request = new WL.ServerAPI.MultiRequest();
			var hide = true;
			for( var i = 0; i < webCallStack.length; ++i ) { list.push(webCallStack[i]); request.addRequest( webCallStack[i].r ); if( !webCallStack[i].hide ) hide = false; }
			for( var i = 0; i < lateRequests.length; ++i ) { list.push(lateRequests[i]); request.addRequest( lateRequests[i].r ); }
				
			window.xmlCallback.doAsyncCallback( window.baseUrl + "/webcall.ashx", 
				"request=" + encodeURIComponent( request.toString() ), 
				function( cbObject )
				{
					cbObject.eventCallback = invokeWebStack_complete.bind( list );
					cbObject.errorCallback = invokeWebStack_error.bind( list );
					cbObject.context = window;
					window.xmlCallback.doWebServerComplete( cbObject );
				}, 
				{hidden:hide,timeout:null} );
			//	window, 
			//	invokeWebStack_complete.bind( list ),
			//	invokeWebStack_error.bind( list ),
			//	hide );
		}
		webCallStack.clear();
		lateRequests.clear();
	}

	var invokeWebStack_complete = function( reader )
	{
		var nodes = reader.getXmlNode().childNodes;
		for( var i = 0; i < this.length; ++i )
		{
			if( nodes[i] != null )
			{
				var errorNode = __selectSingleNode.call( nodes[i], "error" );
				if( errorNode != null )
				{
					var ncode = __selectSingleNode.call( errorNode, "code" ); 
					var ntext = __selectSingleNode.call( errorNode, "message" );
					if( this[i].e && ncode && ntext ) { this[i].e.call( this[i].c, new WL.ErrorInfo( Number( ncode.text ), ntext.text ) ); }
				}
				else { if( this[i].h ) this[i].h.call( this[i].c, new WL.Objects.XmlReader( nodes[i] ) ); }
			}
		}
		this.clear();
	}
	
	var invokeWebStack_error = function( error ) 
	{
		for( var i = 0; i < this.length; ++i ) { if( this[i].e ) this[i].e.call( this[i].c, error ); }
	}
		
	///////////////////////	
	this.getQueueLength = function()
	{
		var list = this.callbackList;
		var l=0;
		for( var i = 0; i < list.length; ++i ) if( !list[i].hidden ) l++;
	//	if( webCallStack.length != 0 ) l++;
		return l;
	}
	this.getLateQueueLength = function() { return lateRequests.length; }
	
	var  hideProgress = function() { if( document.getElementById("progress") ) WL.Utils.setNew( document.getElementById("progress").style, "visibility", "hidden" ); }
	this.showProgress = function() { if( document.getElementById("progress") ) WL.Utils.setNew( document.getElementById("progress").style, "visibility", "visible" ); }	
	this.hideProgress = hideProgress;
	
	this.fixProgress = function( fix )
	{
		this.fix = fix ? this.fix+1 : this.fix-1;
		this.hideProgress = this.fix > 0 ? this.showProgress : hideProgress;
		this.updateWindowStatus( true );
	}
	
	this.updateWindowStatus = function( immediately )
	{
		var count = this.getQueueLength();
		
		if( this.timer ) window.clearTimeout( this.timer );
		
		if( count != 0 )
		{			
			window.status = String.format( "{0} callback request{1} remaining...", count, count > 1 ? "s" : " " );
			this.showProgress();
		}
		else
		{
			var method = function() 
			{
				window.status = "Done"; 
				this.hideProgress();									
   			};
   			
   			if( immediately ) method.call( this );
   			else
   				this.timer = window.setTimeout( method.bind( this ), 150 );
		}
	}
	
	this.abort = function()
	{
		var list = window.xmlCallback.callbackList;
		for( var i = 0; i < list.length; i++ )
		{
			list[i].executed = true;
			list[i].xmlRequest.abort();
		}
		list.clear();
	}
	
	this.unload = function()
	{
		for( var i = 0; i < WL.onclose.length; ++i )
		{
			try { WL.onclose[i](); }
			catch(e){}
		}
		WL.onclose.clear();
		
		if( window.xmlCallback._webcallcookie ) 
			window.clearTimeout( window.xmlCallback._webcallcookie );
		
		webCallStack.removeIf(function(it){return it.big;});
		if( webCallStack.length != 0 || lateRequests.length != 0 )
		{
			var request;
			if( webCallStack.length==1 && lateRequests.length==0 ) request = webCallStack[0].r;
			else
			if( webCallStack.length==0 && lateRequests.length==1 ) request = lateRequests[0].r;
			else
			{
				request = new WL.ServerAPI.MultiRequest();
				for( var i = 0; i < webCallStack.length; ++i ) request.addRequest( webCallStack[i].r );
				for( var i = 0; i < lateRequests.length; ++i ) request.addRequest( lateRequests[i].r );
			}

			var requestString = encodeURIComponent( request.toString() );
			
			webCallStack.clear();
			lateRequests.clear();
			
			window.xmlCallback.doSyncCallback( window.baseUrl + "/webcall.ashx", "request=" + requestString );
		}
	}

	this.ping = function()
	{
		var request = new WL.ServerAPI.Request( WL.Guids.Api.WebGeneral, "Ping" );	
		window.xmlCallback.doWebRequest( request, this, on_ping, on_ping, true ); 
	}
	var on_ping = function() { window.setTimeout( window.xmlCallback.ping, WL.PingInterval ); }
} );

window.xmlCallback	= new WL.XmlCallback();
WL.attachListener( window, "unload", window.xmlCallback.unload );

if( WL.PingInterval != 0 ) window.setTimeout( window.xmlCallback.ping, WL.PingInterval );

if( WL.UseAsyncBigRequest )
{
WL.BigRequest = WL.Class( Object, function()
{
	this.constructor = function( cookie )
	{
		this.wait_cookie = 0;
		this.cookie = cookie;
		this.onProcess = new WL.Objects.Event();
		this.completeCallback = null;
		this.errorCallback = null;
		this.aborted = false;
		this.interval = 5000;
	}

	this.wait = function( completeCallback, errorCallback )
	{
		WL.onclose.push( this.close.bind( this ) );
		window.xmlCallback.fixProgress( true );
		
		if( this.wait_cookie ) window.clearTimeout( this.wait_cookie );
		this.wait_cookie = window.setTimeout( waiting.bind(this), this.interval );
		this.completeCallback = completeCallback;
		this.errorCallback = errorCallback;
	}
	
	var waiting = function()
	{
		var request = new WL.ServerAPI.Request( WL.Guids.Api.BigRequestManager, "GetStateResponseAndClose" );	
			request.body.writeElementString( "cookie", this.cookie );		
		window.xmlCallback.doWebRequest( request, this, on_getState_complete, on_getState_error, false ); 
	}
	
	var on_getState_complete = function( reader )
	{
		this.wait_cookie = window.setTimeout( waiting.bind(this), this.interval );
		
		var state = reader.readInt( "state" );
		switch( state )
		{
			case 0: // processing
				this.onProcess.invoke( this, { percent:reader.readInt( "percent" ), message:reader.readString("message") } );
				break;
			case 1: // complete
				this.aborted = true;
				this.close( { error:false, reader:reader.select( "XmlRpcResponse" ) } );
				break;
			case -1: // aborted
				this.aborted = true;
				this.close( { error:true } );
			//	WL.Utils.assert( true, "big request aborted" );
				break;
			case -2: // error
				this.aborted = true;
				this.close( { error:true, errorInfo: new WL.ErrorInfo( 2, reader.readString( "error" ) ) } );
			//	WL.Utils.assert( true, reader.readString( "error" ) );
				break;
			default:						
				this.aborted = true;
				this.close( { error:true } );
				WL.Utils.assert( true, "Unknown big request state code" );
				break;
		}
	}
	var on_getState_error = function( error )
	{
		this.aborted = true;
		this.close( { error:true } );
		if( error != null ) WL.Utils.assert( true, error.toString() );
		else 				WL.Utils.assert( true, "big request error" );
	}
	
	this.close = function( result )
	{
		window.xmlCallback.fixProgress( false );
		if( this.wait_cookie )
		{
			window.clearTimeout( this.wait_cookie );
			this.wait_cookie = 0;
		}
		
		if( !this.aborted )
		{
			this.aborted = true;
			var request = new WL.ServerAPI.Request( WL.Guids.Api.BigRequestManager, "Abort" );	
			request.body.writeElementString( "cookie", this.cookie );
			window.xmlCallback.doWebRequest( request, this, null, null, false );
		}
		
		if( result && !result.error && this.completeCallback ) this.completeCallback( result.reader );
		if( (!result || result.error) && this.errorCallback ) this.errorCallback( result ? result.errorInfo : null );
		this.completeCallback = null;
		this.errorCallback = null;
	}
} );
} // if( WL.UseAsyncBigRequest )