//Renombramos el método original serializeToString a _serializeToString, para poder "sobrecargarlo"
XMLSerializer.prototype._serializeToString = XMLSerializer.prototype.serializeToString;		

//Esta función permite "sobrecargar" el método serializeToString, de forma que si el parámetro recibido
//es un XMLHttpRequest (tiene responseXML) en lugar de un Document, se serializa la respuesta XML que si que es un Document
XMLSerializer.prototype.serializeToString = function(oNode) 
{
    //Si es un XMLHttpRequest, entonces tendrá responseXML y por tanto el nodo que hay que serializar es el de la respuesta XML
	if(oNode.responseXML) oNode = oNode.responseXML;
	//llamamos al método original para serializar el nodo
	return this._serializeToString(oNode);
};

//Los siguientes fixes solo se aplican a navegadores que no sean IE
if(!_SARISSA_IS_IE && !Sarissa._SARISSA_IS_IE)
{
	//Si el navegador tiene definido el objeto XMLHttpRequest, sobreescribimos la función getDomDocument de Sarissa para que utilice el objeto XMLHttpRequest	
	if (XMLHttpRequest)	
	{     
			Sarissa.getDomDocument = function()
			{
				var oDoc = new XMLHttpRequest();
				//simulamos propiedad async de DOMDocument
				oDoc.async = true;
				//le damos un valor por defecto, ya que da error si no se inicializa
				this.onreadystatechange = null;
				//simulamos la propiedad documentElement de DOMDocument
				this.documentElement = null
				//simulamos la funcion load async de DOMDocument, que carga la URI que se le pasa como un XML
				oDoc.load = function(uri)
				{
				   if(this.async)
				   {
				       //Al parecer, si se reutiliza el mismo objeto XMLHttpRequest para varias peticiones, se "borra"
				       //el contenido de this.onreadystatechange sino se ha vuelto a asignar, por tanto haremos un try-catch de modo que:
				       //1. Si se ha vuelto a asignar, no se producirá excepción y se asignará la nueva función al campo funcion
				       //2. Si no se ha vuelto a asignar, se producirá una excepción al intentar acceser a this.onreadystatechange. 
				       //   En este caso no hacemos nada (en la variable funcion, seguirá existiendo el valor anterior)
				       try
				       {
				   	        this.funcion = this.onreadystatechange;
				   	   }
				   	   catch(e) {}
				   	   //Para evitar problemas al reutilizar el mismo objeto para realizar varias peticiones abortamos la anterior
				   	   //Abortamos cuando ya se ha asignado this.funcion con el valor de onreadystatechange
				       this.abort();
				       //Ponemos a null el onreadystatechange ya que no lo usamos, en su lugar usaremos manejadores de evento
				       this.onreadystatechange = null;
				       //asignamos manejadores de evento al evento readystatechange
				       //el primero se encarga de asignar el documentElement
				       if(this.addEventListener)
				       {
				           this.addEventListener("readystatechange", _sarissa_asigna_documentelement, false);
				       }
				       //con este le decimos que ejecute la función que había en el onreadystatechange y que se ha copiado a la variable funcion, 
				       //es importante que esta se haya asignado antes de llamar y no después!!, ya que ésta solo se asigna al evento en esta función	
				       if (this.funcion != "undefined" && this.funcion != null)
				       {
				   		     if(this.addEventListener)
				             {
				                   this.addEventListener("readystatechange", this.funcion, false);
				             }
				       }
				   }
				   this.open("get", uri, this.async);
				   //comprobamos que esté en estado "Open" (o superior)
				   if(this.readyState < 1) return false;
				   this.send(null);
				   //comprobamos que esté en estado "Enviado" (o superior)
				   if(this.readyState < 2) return false;
				   //Si no es una petición asíncrona, asignamos el documentElement (en lugar de hacerlo en el readystatechange)
				   if(!this.async)
				   {
			            if(this.responseXML != null && this.responseXML != "undefined")
			            {
				            this.documentElement = this.responseXML.documentElement;
				        }
				        else this.documentElement = null;
				   }
				   return true;
				}
				//Devolvemos un objeto XMLHttpRequest que para nuestro propósito se puede usar de forma parecida a un DOMDocument
				return oDoc;
			};
			
		_sarissa_asigna_documentelement = function()
		{
			//Si se ha completado la carga (readyState == 4), asignamos el documentElement que se encuentra en la respuesta XML
			if(this.readyState == 4)
			{
			    if(this.responseXML != null && this.responseXML != "undefined")
			    {
				    this.documentElement = this.responseXML.documentElement;
				}
				else this.documentElement = null;
			}			
		}	
	}

	//Las siguientes funciones implementan las funciones selectSingleNode y selectNodes sobre el objeto XMLHttpRequest
	//simulando ser un objeto del tipo Document que si implementa estas funciones. Para ello, se invoca a los correspondientes
	//métodos del responseXML
		
	if (!XMLHttpRequest.prototype.selectSingleNode) 
	{
		XMLHttpRequest.prototype.selectSingleNode = function (path) 
		{
			if(this.responseXML != null && this.responseXML != "undefined")
		    {
			    return this.responseXML.selectSingleNode(path);
			}
			else return null; 			    
		};
	}
	
	if (!XMLHttpRequest.prototype.selectNodes) 
	{
		XMLHttpRequest.prototype.selectNodes = function (path) 
		{
			if(this.responseXML != null && this.responseXML != "undefined")
		    {
			    return this.responseXML.selectNodes(path);
			}
			else return []; 			    
		};
	}

}
