try{
   var testCommons = new MQObject();
   testCommons = null;
}catch(error){
   throw "You must include mqcommon.js or toolkit api script prior to mqexec.js.";
}



/**
 * Constructs new MQExec Object
 *
 * @class Provides communication layer for requests to a server. Most, but
 * not all, of the functions generate actual requests to the MapQuest
 * Server. Within the context of this object, a Session object is used
 * to maintain information concerning the current client's requests.
 *
 * @param {String/MQExec} strServerNameORmqeObj MapQuest Server name (or) MQExec
 * object to copy the server information.
 * @param {String} strPathToServer Path to the Server
 * @param {int} nServerPort HTTP Port of the Server
 * @param {String} strProxyServerName Name of the server hosting the Proxy page
 * @param (String} strPathToProxyServerPage Path to the Proxy Server page
 * @param {int} nProxyServerPort Port of the Server hosting the Proxy page
 *
 *    strServerName, strPathToServer, and nServerPort are required properties
 *    that need to be set before the first request. If these properties are not
 *    specified, the defaults used for initialization are:
 *
 *    MapServer = localhost
 *    PathToServer = mq
 *    HTTPPort = 80
 *
 *    Please Note: These defaults are not likely to match your configuration.
 *
 *    If MQExec object is provided as the first parameter, remaining parameters
 *    will be ignored and server information will be copied from the provided object.
 *
 *
 * @see MQDBLayerQueryCollection
 * @see MQDTCollection
 * @see MQFeatureCollection
 * @see MQLocation
 * @see MQLocationCollection
 * @see MQMapState
 * @see MQLatLng
 * @see MQPoint
 * @see MQSession
 * @see MQRouteOptions
 * @see MQRouteResults
 * @see MQGeocodeOptionsCollection
 * @see MQStringCollection
 * @see MQRecordSet
 * @see MQLatLngCollection
 * @see MQPointCollection
 * @see MQSearchCriteria
 * @see MQMapCommand
 * @see MQQualityType
 * @see MQMatchType
 */
function MQExec ( strServerNameORmqeObj, strPathToServer, nServerPort,
                  strProxyServerName, strPathToProxyServerPage, nProxyServerPort )
{

   var m_strServerName;
   var m_strServerPath;
   var m_nServerPort;
   var m_strProxyServerPath ;
   var m_strProxyServerName;
   var m_nProxyServerPort;
   var m_lSocketTimeout;
   var m_strXInfo = "";

   if( typeof strServerNameORmqeObj == "string" ) {
      m_strServerName = strServerNameORmqeObj || "localhost";
      m_strServerPath = strPathToServer || "mq";
      m_nServerPort     = nServerPort || 80;
      m_strProxyServerPath = strPathToProxyServerPage || "";
      m_strProxyServerName = strProxyServerName || "";
      m_nProxyServerPort   = nProxyServerPort || 0;
      m_lSocketTimeout = 0;

   } else if(strServerNameORmqeObj.getClassName() &&
            strServerNameORmqeObj.getClassName() == "MQExec" ) {
      m_strServerName = strServerNameORmqeObj.getServerName();
      m_strServerPath = strServerNameORmqeObj.getServerPath();
      m_nServerPort   = strServerNameORmqeObj.getServerPort();
      m_strProxyServerName = strServerNameORmqeObj.getProxyServerName();
      m_nProxyServerPort   = strServerNameORmqeObj.getProxyServerPort();
      m_strProxyServerPath = strServerNameORmqeObj.getProxyServerPath();
      m_lSocketTimeout  = strServerNameORmqeObj.m_lSocketTimeout;
   }


   /**
    * Sets the name of the server which is to be used to satisfy this request.
    * @param {String} strServerName The name of the MapQuest Server which is to
    * be used to satisfy this request.
    * @type     void
    */

   this.setServerName = function(strServerName) {
      m_strServerName = strServerName;

   };

  /**
    * Returns the name of the server which will be used to satisfy this
    * request.
    *
    * @return   The name of the server which will be used to satisfy
    * this request.
    * @type      String
    */

   this.getServerName= function() {
      return m_strServerName;
   };


   /**
    * Sets the path to the server which is to be used to satisfy this request.
    *
    * @param   {String}   strServerPath  The path to the server which is to be used
    * to satisfy this request.
    * @type      void
    */

   this.setServerPath = function(strServerPath) {
      m_strServerPath = strServerPath;
   };


   /**
    * Returns the path to the server which will be used to satisfy this
    * request.
    *
    * @return  The path to the  server which will be used to satisfy this
    * request.
    * @type    String
    */

   this.getServerPath= function() {
      return m_strServerPath;
   };


   /**
    * Sets the port number to the server which is to be used to satisfy this
    * request.
    *
    * @param  {int}  nServerPort The port number of the server which is to be
    *                      used to satisfy this request.
    * @type    void
    */

   this.setServerPort = function(nServerPort) {
      m_nServerPort = nServerPort;

   };

   /**
    * Returns the port number of the server which will be used to satisfy
    * this request.
    *
    * @return    The port number of the server which will be used to satisfy
    *            this request.
    * @type    int
    */

   this.getServerPort= function() {
      return m_nServerPort;
   };



  /**
    * Sets the name or IP of the proxy server to connect to.
    * The name should not contain any leading or trailing slashes ("/").
    *
    * @param  {String} strProxyServerName The name of the proxy server.
    * @type    void
    */

   this.setProxyServerName = function(strProxyServerName) {
      m_strProxyServerName = strProxyServerName;

   };

  /**
    * Returns the name or IP of the proxy server to connect to.
    *
    * @return The name of the proxy server.
    * @type String
    */

   this.getProxyServerName = function() {

      return m_strProxyServerName;

   };

   /**
    * Sets the path to the proxy server which is to be used to satisfy this request.
    *
    * @param  (String} strProxyServerPath The path to the server which is to be used
    * to satisfy this request.
    * @type void
    */

   this.setProxyServerPath = function(strProxyServerPath) {
      m_strProxyServerPath = strProxyServerPath;

   };


   /**
    * Returns the path to the proxy server page which will be used to satisfy this
    * request.
    *
    * @return  The path to the proxy server page which will be used to satisfy this
    *          request.
    * @type    String
    */

   this.getProxyServerPath = function() {
      return m_strProxyServerPath;
   };

   /**
    * Sets the port to connect to the proxy server with.
    *
    * @param {int}  nProxyServerPort The proxy server port number.
    * @type void
    */

   this.setProxyServerPort = function(nProxyServerPort) {
      m_nProxyServerPort = nProxyServerPort;

   };

   /**
    * Returns the port number to connect to the proxy server with.
    *
    * @return The proxy server port number.
    * @type int
    */

   this.getProxyServerPort = function() {
      return m_nProxyServerPort;
   };


   /**
    * Sets data to be passed to the server to be logged with any
    * subsequent requests in the transaction log. (Max 8 characters)
    *
    * @param {String} strXInfo Transaction Info.
    *
    * @type void
    */

   this.setTransactionInfo = function(strXInfo) {
      if (strXInfo.length > 32)
         m_strXInfo = strXInfo.substring(0, 32);
      else
         m_strXInfo = strXInfo;

   };


   /**
    * Gets data to be passed to the server to be logged with any
    * subsequent requests in the transaction log.
    *
    * @return Transaction Information
    * @type String
    */

   this.getTransactionInfo = function() {
      return m_strXInfo;
   };


}

   /* Defined transaction versions */
   MQExec.prototype.ROUTE_VERSION = "2";
   MQExec.prototype.SEARCH_VERSION = "0";
   MQExec.prototype.GEOCODE_VERSION = "1";
   MQExec.prototype.ROUTEMATRIX_VERSION = "0";
   MQExec.prototype.GETRECORDINFO_VERSION = "0";
   MQExec.prototype.REVERSEGEOCODE_VERSION = "0";
   MQExec.prototype.GETSESSION_VERSION = "1";


   /**
    * Prepares request XML data to be sent to the server for a given transaction
    * and set of request objects.
    *
    * @param {String} strTransaction Name of the transaction
    *
    * @param {Array} arrRequest Array of request objects to form the XML
    *
    * @param {String} strVersion Version of the transaction implementation
    *
    * @type void
    *
    * @private
    */
   MQExec.prototype.getRequestXml = function(strTransaction, arrRequest, strVersion) {

      var arrXmlBuf = new Array();
      var version = strVersion || "0";
      arrXmlBuf.push("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
      arrXmlBuf.push("<" + strTransaction + " Version=\"" + version + "\">\n");
      for (var i=0; i < arrRequest.length; i++) {
         arrXmlBuf.push(arrRequest[i].saveXml());
         arrXmlBuf.push("\n");
      }
      arrXmlBuf.push("</" + strTransaction + ">");
      return arrXmlBuf.join("");

   };

  /**
    * Performs the given transaction by making AJAX call to the Proxy Server page.
    *
    * @param {String} strTransaction Name of the transaction
    *
    * @param {Array} arrRequest Array of request objects
    *
    * @type void
    *
    * @private
    */
   MQExec.prototype.doTransaction = function(strTransaction, arrRequest, strVersion ) {

      var xmlDoc;
      var strResXml;
      var http_request = mqXMLHttpRequest();
      var strUrl = "";
      arrRequest.push( new MQAuthentication(this.getTransactionInfo()));
      var strReqXml = this.getRequestXml(strTransaction, arrRequest, strVersion);

      if(this.getProxyServerName() != "") {
         strUrl += "http://" + this.getProxyServerName();
         if(this.getProxyServerPort() != 0) {
            strUrl += ":" + this.getProxyServerPort();
         }
         strUrl += "/";
      }

      strUrl += this.getProxyServerPath();
      strUrl += "?sname=" + this.getServerName();
      strUrl += "&spath=" + this.getServerPath();
      strUrl += "&sport=" + this.getServerPort();
      display("mqXmlLogs", "Request URL: ", strUrl, "rURL", "mqDisplay");
      display("mqXmlLogs", "Request XML: ", strReqXml, "", "mqDisplay");
      http_request.open("POST", strUrl, false);
      http_request.send(strReqXml);
      if (http_request.status == 200) {
          xmlDoc= http_request.responseXML;
      }
      else {
         alert(   "HTTP Status: " + http_request.status +
               " (" + http_request.statusText + ")\n" +
               "Details: \n" + http_request.responseText
              );
         xmlDoc = null;
      }
      display("mqXmlLogs", "Response XML: ", mqXmlToStr(xmlDoc), "resXML", "mqDisplay");
      return xmlDoc;
   };


   /**
    * Method to geocode an address or an intersection. Geocode options supply
    * the QualityType and MatchType.
    *
    * @param {MQAddress} mqaAddress  The Address object containing the necessary info for
    * the address.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param {MQLocationCollection} mqlcLocations  The LocationCollection to hold the results of the
    * geocode.
    *
    * @param {MQAutoGeocodeCovSwitch/MQGeocodeOptionsCollection} theOptions
    * The AutoGeocodeCovSwitch or MQGeocodeOptionsCollection to select a set of
    * options stored on the server.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @type void
    */

   MQExec.prototype.geocode = function(mqaAddress, mqlcLocations, theOptions) {

      var xmlDoc;
      var strXml;
      var arrRequest = new Array();

      if(mqaAddress == null || (mqaAddress.getClassName() !== "MQAddress" && mqaAddress.getClassName() !== "MQSingleLineAddress")) {
           throw "Null or Illegal Argument passed for MQAddress";
      } else {
           arrRequest.push(mqaAddress);
      }

      if(mqlcLocations == null || mqlcLocations.getClassName() !== "MQLocationCollection") {
           throw "Null or Illegal Argument passed for MQLocationCollection";
      }

      if(theOptions != null) {
         if(theOptions.getClassName() !== "MQAutoGeocodeCovSwitch" &&
             theOptions.getClassName() !== "MQGeocodeOptionsCollection" ) {
            throw "Illegal Argument passed for Geocode Options";
         } else {
            arrRequest.push(theOptions);
         }
      }

      mqLogTime("MQExec.geocode: Transaction Start");
      xmlDoc = this.doTransaction("Geocode", arrRequest, this.GEOCODE_VERSION);
      mqLogTime("MQExec.geocode: Transaction End");

      mqLogTime("MQExec.geocode: Loading of GeocodeResponse Start");
      strXml = mqXmlToStr(mqGetNode(xmlDoc, "/GeocodeResponse/LocationCollection"));
      mqlcLocations.loadXml(strXml);
      mqLogTime("MQExec.geocode: Loading of GeocodeResponse End");

      display("results", "Response", mqXmlToStr(xmlDoc), "", "mqDisplay");

   };



   /**
    * Method to batch geocode a collection of locations. Geocode options supply
    * the QualityType and MatchType.
    * 
    * @param {MQLocationCollection} mqlcLocations  The LocationCollection containing the
    * necessary info for the addresses to be geocode.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param {MQLocationCollectionCollection} mqlccLocations  The LocationCollectionCollection
    * used to hold the results of the geocode.
    *
    * @param {MQAutoGeocodeCovSwitch/MQGeocodeOptionsCollection} theOptions
    * The AutoGeocodeCovSwitch or MQGeocodeOptionsCollection to select a set of
    * options stored on the server.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @type void
    */

   MQExec.prototype.batchGeocode = function(mqlcLocations, mqlccLocations, theOptions) {

      var xmlDoc;
      var strXml;
      var arrRequest = new Array();

      if(mqlcLocations == null || mqlcLocations.getClassName() !== "MQLocationCollection") {
           throw "Null or Illegal Argument passed for MQLocationCollection";
      } else {
           arrRequest.push(mqlcLocations);
      }

      if(mqlccLocations == null || mqlccLocations.getClassName() !== "MQLocationCollectionCollection") {
           throw "Null or Illegal Argument passed for MQLocationCollectionCollection";
      }

      if(theOptions != null) {
         if(theOptions.getClassName() !== "MQAutoGeocodeCovSwitch" &&
             theOptions.getClassName() !== "MQGeocodeOptionsCollection" ) {
            throw "Illegal Argument passed for Geocode Options";
         } else {
            arrRequest.push(theOptions);
         }
      }

      mqLogTime("MQExec.batchGeocode: Transaction Start");
      xmlDoc = this.doTransaction("BatchGeocode", arrRequest, this.GEOCODE_VERSION);
      mqLogTime("MQExec.batchGeocode: Transaction End");

      mqLogTime("MQExec.batchGeocode: Loading of GeocodeResponse Start");
      strXml = mqXmlToStr(mqGetNode(xmlDoc, "/BatchGeocodeResponse/LocationCollectionCollection"));
      mqlccLocations.loadXml(strXml);
      mqLogTime("MQExec.batchGeocode: Loading of GeocodeResponse End");

      display("results", "Response", mqXmlToStr(xmlDoc), "", "mqDisplay");

   };



   /**
    * Calculates a route using a collection of locations as origin and
    * destination. These locations can be Address, GeoAddress,
    * Intersection, or GeoIntersection objects.
    *
    * @param {MQLocationCollection} mqlcLocations Collection of locations.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param {MQRouteOptions} mqroOptions Route options object, to modify
    * behavior of route.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param {MQRouteResults} mqrrResults The results of the route request.
    *
    * @param {String} strSessionUID The unique Session ID.
    *
    * @param {MQRectLL} mqRectLL The bounding box to provide to the TileMap
    * ToolKit. This parameter is optional
    *
    * @type void
    */

   MQExec.prototype.doRoute = function(mqlcLocations, mqroOptions, mqrrResults, strSessionUID, mqRectLL) {

      var xmlDoc;
      var strXml;
      var arrRequest = new Array();

      if(mqlcLocations == null || mqlcLocations.getClassName() !== "MQLocationCollection") {
         throw "Null or Illegal Argument passed for MQLocationCollection";
      } else {
         arrRequest.push(mqlcLocations);
      }
      if(mqroOptions == null || mqroOptions.getClassName() !== "MQRouteOptions") {
         throw "Null or Illegal Argument passed for MQRouteOptions";
      } else {
         arrRequest.push(mqroOptions);
      }
      if(mqrrResults == null || mqrrResults.getClassName() !== "MQRouteResults") {
         throw "Null or Illegal Argument passed for MQRouteResults";
      } else {
         var sessionId = strSessionUID || "";
         arrRequest.push(new MQXmlNodeObject("SessionID",sessionId) );
      }

      mqLogTime("MQExec.doRoute: Transaction Start");
      xmlDoc = this.doTransaction("DoRoute", arrRequest, this.ROUTE_VERSION);
      mqLogTime("MQExec.doRoute: Transaction End");

      mqLogTime("MQExec.doRoute: Loading of RouteResults Start");
      strXml = mqXmlToStr(mqGetNode(xmlDoc, "/DoRouteResponse/RouteResults"));
      mqrrResults.loadXml(strXml);
      mqLogTime("MQExec.doRoute: Loading of RouteResults End");

      display("results", "Response", mqXmlToStr(xmlDoc), "", "mqDisplay");

      if(mqRectLL !== null && sessionId !== ""){
         this.getRouteBoundingBoxFromSessionResponse(sessionId, mqRectLL);
      }

   };

  /**
    * Generates a request to the MapQuest server (as specified by the
    * server name, path, and port number) to create a user Session.
    * The Session is assigned a unique identifier which is used to
    * access and update the Session information.
    *
    * @param  {MQSession} mqsSession Object containing objects for the session.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @return The unique Session identifier.
    *
    * @type String
    */

   MQExec.prototype.createSessionEx = function(mqsSession) {

      var xmlDoc;
      var strSessId;
      var arrRequest = new Array();
      if(mqsSession == null || mqsSession.getClassName() !== "MQSession") {
         throw "Null or Illegal Argument passed for MQSession";
      } else {
         arrRequest.push(mqsSession);
      }

      xmlDoc = this.doTransaction("CreateSession", arrRequest);
      strSessId = mqGetNodeText(mqGetNode(xmlDoc, "/CreateSessionResponse/SessionID"));

      return strSessId;
   };


   MQExec.prototype.getSession = function(strSessionID, mqObj) {

      // TO-DO: do class name validations.
      var xmlDoc;
      var strXml;
      var sessionId = strSessionID || "";
      var arrRequest = new Array();
      arrRequest.push(new MQXmlNodeObject("SessionID",sessionId) );

      xmlDoc = this.doTransaction("GetSession", arrRequest, this.GETSESSION_VERSION);
      if(mqObj.getClassName()==="MQMapState"){
         strXml = mqXmlToStr(mqGetNode(xmlDoc, "/GetSessionResponse/Session/MapState"));
         mqObj.loadXml(strXml);
      } else if(mqObj.getClassName()==="MQSession"){
         strXml = mqXmlToStr(mqGetNode(xmlDoc, "/GetSessionResponse/Session"));
         mqObj.loadXml(strXml);
      }
   };


   /**
    * Calculates a route matrix. Either a drive time (many-to-many) or a
    * multi-destination (one-to-many) route.
    *
    * @param  {MQLocationCollection} mqlcLocations Collection of location objects.
    * The first member of the collection is the origin. If allToAll is true then
    * the last member is the destination. Each location must be a GeoAddress
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param  {boolean} bAllToAll If true then a matrix of time and distance from
    * each location to all others is found. If false, time and distance from the
    * first location (origin) to all others is found.
    *
    * @param  {MQRouteOptions} mqroOptions Specifies options for the route (fastest vs.
    * shortest, coverage to use, roads to avoid, etc.).
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param  {MQRouteMatrixResults} mqrmrResults Contains the time and distance matrix as
    * well as the status of the call (success, failure, partial success)
    *
    * @type void
    *
    */

   MQExec.prototype.doRouteMatrix = function(mqlcLocations, bAllToAll, mqroOptions, mqrmrResults) {

      var xmlDoc;
      var strXml;
      var arrRequest = new Array();

      if(mqlcLocations == null || mqlcLocations.getClassName() !== "MQLocationCollection") {
           throw "Null or Illegal Argument passed for MQLocationCollection";
      } else {
           arrRequest.push(mqlcLocations);
      }
      if( bAllToAll == null || typeof bAllToAll != "boolean") {
           throw "Null or Illegal Argument passed for bAllToAll";
      } else {
           var iAllToAll = bAllToAll ? 1 : 0;
           arrRequest.push(new MQXmlNodeObject("AllToAll", iAllToAll));
      }
      if(mqroOptions == null || mqroOptions.getClassName() !== "MQRouteOptions") {
           throw "Null or Illegal Argument passed for MQRouteOptions";
      } else {
           arrRequest.push(mqroOptions);
      }
      if(mqrmrResults == null || mqrmrResults.getClassName() !== "MQRouteMatrixResults") {
           throw "Null or Illegal Argument passed for MQRouteMatrixResults";
      }

      mqLogTime("MQExec.doRoute: Transaction Start");
      xmlDoc = this.doTransaction("DoRouteMatrix", arrRequest, this.ROUTEMATRIX_VERSION);
      mqLogTime("MQExec.doRoute: Transaction End");

      mqLogTime("MQExec.doRoute: Loading of RouteResults Start");
      strXml = mqXmlToStr(mqGetNode(xmlDoc, "/DoRouteMatrixResponse/RouteMatrixResults"));
      mqrmrResults.loadXml(strXml);
      mqLogTime("MQExec.doRoute: Loading of RouteResults End");

      display("results", "Response", mqXmlToStr(xmlDoc), "", "mqDisplay");

   };


   /**
    * Generates a request to the MapQuest server (as specified by the server
    * name, path, and port number) to perform a DB Search based on either the
    * recordIds received or the extraCriteria info of the dblayerquery. The
    * resulting recordset contains fields specified by the scFieldNames param.
    *
    * @param  {MQStringCollection} mqscFieldNames containing the names of the fields
    * to return, or blank for all fields.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param  {MQDBLayerQuery} mqdlqQuery  Contains the name of the dblayer/table to query.
    * Optionally contains ExtraCriteria.  Utilized only if RecordIds are empty.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param {MQRecordSet}  mqrsResults  The Returned RecordSet containg the records and
    * fields matching the input parameters.
    *
    * @param  {MQStringCollection} mqscRecIds  RecordIdentifiers of the records to return
    * stored in a StringCollection.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @type void
    *
    */

   MQExec.prototype.getRecordInfo = function(mqscFieldNames, mqdlqQuery, mqrsResults, mqscRecIds) {

      var xmlDoc;
      var strXml;
      var arrRequest = new Array();

      if( mqscFieldNames == null || mqscFieldNames.getClassName() !== "MQStringCollection" ) {
           throw "Null or Illegal Argument passed for MQStringCollection";
      } else {
            var fields = new MQStringCollection();
            fields.setM_Xpath("Fields");
            fields.append(mqscFieldNames);
            arrRequest.push(fields);
      }
      if( mqdlqQuery == null || mqdlqQuery.getClassName() !== "MQDBLayerQuery" ) {
           throw "Null or Illegal Argument passed for MQDBLayerQuery";
      } else {
           arrRequest.push(mqdlqQuery);
      }
      if( mqrsResults == null || mqrsResults.getClassName() !== "MQRecordSet" ) {
           throw "Null or Illegal Argument passed for MQRecordSet";
      }
      if( mqscRecIds == null || mqscRecIds.getClassName() !== "MQStringCollection") {
           throw "Null or Illegal Argument passed for MQStringCollection";
      } else {
            var recordIds = new MQStringCollection();
            recordIds.setM_Xpath("RecordIds");
            recordIds.append(mqscRecIds);
            arrRequest.push(recordIds);
      }

      mqLogTime("MQExec.getRecordInfo: Transaction Start");
      xmlDoc = this.doTransaction("GetRecordInfo", arrRequest, this.GETRECORDINFO_VERSION);
      mqLogTime("MQExec.getRecordInfo: Transaction End");

      mqLogTime("MQExec.getRecordInfo: Loading of RecordSet Start");
      strXml = mqXmlToStr(mqGetNode(xmlDoc, "/GetRecordInfoResponse/RecordSet"));
      mqrsResults.loadXml(strXml);
      mqLogTime("MQExec.getRecordInfo: Loading of RecordSet End");

      display("results", "Response", mqXmlToStr(xmlDoc), "", "mqDisplay");

   };


   /**
    * Finds the address at a given latitude/longitude position.
    *
    * @param {MQLatLng}  mqllLatLng The latitude/longitude position to use for
    * the reverse geocode.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param {MQLocationCollection}  mqlcLocations A LocationCollection in
    * which to return the results of the reverse geocode.  It will contain
    * only GeoAddress objects.
    *
    * @param {String}  strMapCovName The name of the mapping coverage to be
    * used for the reverse geocode.
    *
    * @param {String}  strGeocodeCovName An optional parameter, specifies the
    * geocode coverage to use for the reverse geocode. If specified, using
    * this geocode coverage, a ZIP code lookup will be performed on the addresses
    * found in the mapping data to verify and fill in the city/state information
    * for the address. If not specified, only ZIP code and, if available, street
    * information found in the mapping data will be returned.
    *
    * @type void
    *
    */

   MQExec.prototype.reverseGeocode = function(mqllLatLng, mqlcLocations, strMapCovName, strGeocodeCovName) {

      var xmlDoc;
      var strXml;
      var arrRequest = new Array();

      if( mqllLatLng == null || mqllLatLng.getClassName() !== "MQLatLng" ) {
           throw "Null or Illegal Argument passed for MQLatLng";
      } else {
           arrRequest.push(mqllLatLng);
      }
      if( mqlcLocations == null || mqlcLocations.getClassName() !== "MQLocationCollection" ) {
           throw "Null or Illegal Argument passed for MQLocationCollection";
      }
      var mapPool = strMapCovName || "";
      arrRequest.push(new MQXmlNodeObject("MapPool", mapPool));

      var geocodePool = strGeocodeCovName || "";
      arrRequest.push(new MQXmlNodeObject("GeocodePool", geocodePool));

      mqLogTime("MQExec.reverseGeocode: Transaction Start");
      xmlDoc = this.doTransaction("ReverseGeocode", arrRequest, this.REVERSEGEOCODE_VERSION);
      mqLogTime("MQExec.reverseGeocode: Transaction End");

      mqLogTime("MQExec.reverseGeocode: Loading of Response Start");
      strXml = mqXmlToStr(mqGetNode(xmlDoc, "/ReverseGeocodeResponse/LocationCollection"));
      mqlcLocations.loadXml(strXml);
      mqLogTime("MQExec.reverseGeocode: Loading of Response End");

      display("results", "Response", mqXmlToStr(xmlDoc), "", "mqDisplay");

   };


   /**
    * Generates a request to the MapQuest server (as specified by the
    * server name, path, and port number) to perform a search and
    * return the results in a FeatureCollection object.
    *
    * @param  {MQSearchCriteria} mqscCriteria  Spatial parameters for the search.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param {MQFeatureCollection}  mqfcSearchResults Search results.
    *
    * @param {String}  strCoverageName  The name of the map data coverage if searching
    * for features in the map data.
    *
    * @param {MQDBLayerQueryCollection}  mqdlqcDbLayers  Database parameters for the search.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param {MQFeatureCollection}  mqfcFeatures  A FeatureCollection to also be searched
    * based on the spatial criteria.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @param {MQDTCollection}  mqdcDisplayTypes  A DTCollection to narrow the search. Only those
    * features with display types corresponding to those in this collection will be returned.
    * (Please Note:  This object will not be updated, it is simply used for the request.)
    *
    * @type void
    */

   MQExec.prototype.search = function(mqscCriteria, mqfcSearchResults, strCoverageName,
                              mqdlqcDbLayers, mqfcFeatures, mqdcDisplayTypes)      {
      var xmlDoc;
      var strXml;
      var arrRequest = new Array();
      var strName = mqscCriteria ? mqscCriteria.getClassName(): null;

      if( strName == null || (strName !== "MQSearchCriteria" &&
            strName !== "MQRadiusSearchCriteria" && strName !== "MQRectSearchCriteria" &&
            strName !== "MQPolySearchCriteria" && strName !== "MQCorridorSearchCriteria" )) {
           throw "Null or Illegal Argument passed for Search Criteria";
      } else {
             arrRequest.push(mqscCriteria);
      }
      if(mqfcSearchResults == null || mqfcSearchResults.getClassName() !== "MQFeatureCollection") {
           throw "Null or Illegal Argument passed for MQFeatureCollection";
      }
      if( typeof strCoverageName !== "string" ) {
           throw "Illegal Argument passed for strCoverageName";
      } else {
            arrRequest.push(new MQXmlNodeObject("CoverageName", strCoverageName));
      }

      if(mqdlqcDbLayers != null && mqdlqcDbLayers.getClassName() !== "MQDBLayerQueryCollection") {
           throw "Illegal Argument passed for MQRouteOptions";
      } else if(mqdlqcDbLayers == null) {
            mqdlqcDbLayers = new MQDBLayerQueryCollection();
      }
      arrRequest.push(mqdlqcDbLayers);

      if(mqfcFeatures != null && mqfcFeatures.getClassName() !== "MQFeatureCollection") {
      throw "Illegal Argument passed for MQFeatureCollection";
      } else if( mqfcFeatures == null ) {
      mqfcFeatures = new MQFeatureCollection();
      }
      arrRequest.push(mqfcFeatures);

      if(mqdcDisplayTypes != null && mqdcDisplayTypes.getClassName() !== "MQDTCollection") {
          throw "Illegal Argument passed for MQDTCollection";
     } else if(mqdcDisplayTypes == null ) {
          mqdcDisplayTypes = new MQDTCollection();
      }
      arrRequest.push(mqdcDisplayTypes);

      mqLogTime("MQExec.Search: Transaction Start");
      xmlDoc = this.doTransaction("Search", arrRequest, this.SEARCH_VERSION);
      mqLogTime("MQExec.Search: Transaction End");

      mqLogTime("MQExec.Search: Loading of Search results Start");
      strXml = mqXmlToStr(mqGetNode(xmlDoc, "/SearchResponse/FeatureCollection"));
      mqfcSearchResults.loadXml(strXml);
      mqLogTime("MQExec.Search: Loading of Search results End");

      display("results", "Response", mqXmlToStr(xmlDoc), "", "mqDisplay");

   };

   /**
    * Sets the mqRectLL appropriately for tilemaps routing
    *
    * @param {String} strSessionUID The unique Session ID.
    *
    * @param {MQRectLL} mqRectLL The bounding box for the route in the session.
    *
    * @type void
    * @private
    */

   MQExec.prototype.getRouteBoundingBoxFromSessionResponse = function(sessionId, mqRectLL) {

      var xmlDoc;
      var strXml;
      var arrRequest = new Array();

      if(mqRectLL == null) {
         throw "Null or Illegal Argument passed for MQRectLL";
      }
      arrRequest.push(new MQXmlNodeObject("SessionID",sessionId) );

      xmlDoc = this.doTransaction("GetRouteBoundingBoxFromSession", arrRequest);

      mqLogTime("MQExec.doRoute: Loading of MQRectLL Start");
      var nodes = xmlDoc.documentElement.childNodes;
      var ul = new MQLatLng();
      ul.loadXml(mqXmlToStr(nodes[0]));
      var lr = new MQLatLng();
      lr.loadXml(mqXmlToStr(nodes[1]));
      mqRectLL.setUpperLeft(ul);
      mqRectLL.setLowerRight(lr);
      mqLogTime("MQExec.doRoute: Loading of MQRectLL End");
   };

   /**
    * Returns a value indicating whether or not this object has been
    * initialized to a map server and port number.
    *
    * @return <code><b>true</b></code> if the port number or the Server
    *         name is not equal to their uninitialized values, <code><b>
    *         false</b></code> otherwise.
    *
    * @type boolean
    *
    * @private
    */

   MQExec.prototype.isAlive = function() {

      if( this.getServerPort() == -1 || this.getServerName() == "" )
         return false;
      return true;

   };


   /**
    * Returns the string which specifies the coverage information requested
    * directly via an http request.
    *
    * @param {int}  lType Type of info to return,
    * 0=CoverageInfo, 1=MapDataSelectorInfo.
    *
    * @return The string which specifies the server information.
    *
    * @type Document
    */

   MQExec.prototype.getServerInfo = function( lType ) {

      if (!this.isAlive())
         return null;

      var strReqXml;
      var xmlDoc;
      var strXml;
      var type = lType || 0;
      var arrRequest = new Array();
      if( typeof type !== "number" ) {
         throw "Illegal Argument passed for lType";
      } else {
         arrRequest.push(new MQXmlNodeObject("Type", type));
      }

      mqLogTime("MQExec.GetServerInfo: Transaction Start");
      xmlDoc = this.doTransaction("GetServerInfo", arrRequest);
      mqLogTime("MQExec.GetServerInfo: Transaction End");
      display("results", "Response", mqXmlToStr(xmlDoc), "", "mqDisplay");
      return xmlDoc;

   };


