/** 
 * @fileoverview MasterQuery is a client side library written in 
 * JavaScript designed to simplify the development on CUIs by 
 * creating a common interface into LexisNexis APIs for developers. 
 * Many tasks that would normally require a significant amount of 
 * coding time can now be done simply by updating the site’s 
 * properties file. The new interactive developer information window 
 * allows for Lexis Nexis employees to easily see what is being sent 
 * through the CUI and test alternative syntax. 
 * <br /><br />
 * One of the biggest advantages is that a site can be prepared for 
 * conversion over to Rosetta simply by implementing the site using 
 * MasterQuery. Once the Nexis.com URL API is released a developer 
 * updates the site’s properties and you’re good to go. 
 * <br /><br />
 * Note that since MasterQuery is a code library it is not meant to 
 * have any effect on the customer’s user experience.
 * <br /><br />
 * <b>CONVERTING A SITE OVER TO MasterQuery</b>

<ol>
	<li><b>Create a properties file</b><br /><br />
		A good place to look for examples is in the directory
		/clients/controls/MasterQuery/lib/propertyFiles/
		<br /><br />
		It is possible for a site to have multiple properties files for different instances of MasterQuery. See /clients/controls/MasterQuery/demos/_loader/ for an example.<br /><br />
	</li>
	<li><b>Include the required libraries</b><br /><br />
		<pre>&lt;script language=&quot;javascript&quot; src=&quot;/clients/jslib/utils.js&quot;&gt;&lt;/script&gt;
&lt;script language=&quot;javascript&quot; src=&quot;/clients/controls/MasterQuery/MQInclude.asp&quot;&gt;&lt;/script&gt;</pre>
	</li>
	<li><b>Set the API in the properties file</b><br /><br />
	api=1  CUI Builder<br />
	api=2  CUI International<br />
	api=3  Dossier<br />
	api=4  Get and Print<br />
	api=5  Professional<br />
	api=6  URL API<br />
	api=7  V1 Portfolio<br />
	api=8  V1 Search<br />
	api=9  V1 Search Form<br />
	api=10 V1 SNews<br />
	api=11 XLink<br />
	api=12 Seisint<br />
	api=13 Dossier Forms<br />
	api=14 Nexis Search Form<br />
	api=18 Lexis Public Records<br />
	api=19 Rosetta Public Records<br /><br />
	</li>
	<li><b>Set the common API paramaters in the properties file</b><br />
<pre>target=_blank
originationCode=00004
menu=126NC9
mj=1
MIDDLEWARE_CODE=NP
client=seisinttest</pre>

In the past these would be either hidden fields in the CUI search form or link paramaters.  
<br /><br />
</li>
<li><b>Instantiate a  MasterQuery Object and punch in the forms values that you want to send to 
the API</b><br />

<pre>var chunnel = LNParser.propertyFactory("properties.txt");
chunnel.setSearch(query.value);
chunnel.setAfter(after.value);
chunnel.setSource(src.value);
chunnel.setClient(clientid.value);
chunnel.submit();</pre>

See the Class documentation for other usage examples.<br /><br />

</li>
<li><b>Advanced Options</b><br />
There are several demo CUIs that demonstrate other techiniques using MasterQuery:<br /><br />
<dl>
	<dt>Seisint: /clients/controls/MasterQuery/demos/_seisint/</dt>
	<dd>This shows how to use XLink's Seisint sources. Normal L/N query syntax does not apply. For examples of MasterQuery Seisint in production see {@link http://csdev:8080/clients/controls/MasterQuery/docs/checklist.xls this spreadsheet}.<br /></dd>
	<dt>Embedded ID: /clients/controls/MasterQuery/demos/_chain/</dt>
	<dd>This demo CUI takes a MasterQuery Object, redirects it to another page where the ID 
		is included and sent on it's way.<br /></dd>
	<dt>Rosetta URL API: /clients/controls/MasterQuery/demos/_url_api/</dt>
	<dd><br /></dd>
	<dt>Loading Multiple Property Files: /clients/controls/MasterQuery/demos/_loader/</dt>
	<dd><br /></dd>
</dl>


</li>

<li><b>Smart Tools Verbs</b><br />
The Implelentor for Nexis.com Smart Tools has been redone so as to support a
framework that matches the verb concept under Rosetta. Instead of their being
six different implementors, there is instead just one that in which the API
can be changed depending on the verb passed in. The verb matches the filename
of the url passed in. 
<br /><br />
The Smart Tools verb used can be set through various methods. The LNParser.factory()
method determines the verb automatically based upon the URL passed in. For forms
one needs to set the verb property either through MasterQuery's set() method or via
a passed in property file.

<pre>
	verb=v1_search (default)
	verb=v1_portfolio
	verb=v1_searchform
	verb=v1_snews
	verb=v1_dossier_launch_forms
	verb=search/searchform
	
	chunnel.set("verb", "v1_searchform")
	
	var chunnel = LNParser("http://web.lexis-nexis.com/api.universe/search/searchform?id=1928")
</pre>

If no verb is set v1_search is used by default. 
</li>

</ol>

 * @author Christopher Baker <Christopher.Baker@lexisnexis.com>
 * @version 0.1 
 */

//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// CONSTANTS

var NEW_WINDOW_FEATURES = 'status=yes,resizable=yes,menubar=yes,scrollbars=yes,toolbar=yes,directories=yes,location=yes'

/**
 * MasterQuery
 *
 * @class Core data class for the MasterQuery API. MasterQuery Objects are
 * used by various Implementors to create specific LexisNexis calls. The main
 * task of the class is to hold values used by L/N APIs. 
 * <br /><br />
 * USAGE:
 *<pre>
 *     var chunnel = new MasterQuery(MasterQuery.API_XLINK);
 *     chunnel.setSearch("Bush and AWOL");
 *     chunnel.setSource("NEWS;90DAYS");
 *     chunnel.setClient("999-5465");
 *     chunnel.setAfter("5:DY");
 *     chunnel.set("LNAUTHSCHEME", "CP");
 *     chunnel.submit();</pre>
 *
 * The recommended way to create a MasterQuery Object is through the 
 * {@link LNParser} factory methods.
 *
 * @param {int} The implementor that the Builder will call
 * @version 0.1 
 * @constructor
 */
function MasterQuery(intAPI)
{
	// Set the API
	if (intAPI) 
	{
		this.setAPI(intAPI);
	}
	else
	{
		this.setAPI(MasterQuery.DEFAULT_API);
	}
	this.search = "";
	this.source = "";
	this.originationCode = "";
	
	this.method = "GET";
	this.target = "_self";
	this.TOCTarget = "";
	
	this.protocol = "http:";
}

MasterQuery.NO_DEBUG = false;

/**
 * LexisNexis API Constant for CUI Builder
 * @type int
 */
MasterQuery.API_CUI_BUILDER       = 1;
/**
 * LexisNexis API Constant for CUI International
 * @type int
 */
MasterQuery.API_CUI_INTERNATIONAL = 2;
/**
 * LexisNexis API Constant for Dossier Searches
 * @type int
 */
MasterQuery.API_DOSSIER           = 3;
/**
 * LexisNexis API Constant for Get and Print
 * @type int 
 */
MasterQuery.API_GET_AND_PRINT     = 4;
/**
 * LexisNexis API Constant for LN Professional
 * @type int 
 */
MasterQuery.API_PROFESSIONAL      = 5;
/**
 * LexisNexis API Constant for the Rosetta URL API
 * @type int 
 */
MasterQuery.API_URL_API           = 6;
/**
 * @deprecated
 * @type int
 */
MasterQuery.API_V1_PORTFOLIO      = 7;
/**
 * LexisNexis API Constant for v1 Search
 * @type int
 */
MasterQuery.API_V1_SEARCH         = 8;
/**
 * Constant casts into v1_search with searchform verb.
 * @type int
 */
MasterQuery.API_V1_SEARCHFORM     = 9;
/**
 * @type int 
 */
MasterQuery.API_V1_SNEWS          = 10;
/**
 * LexisNexis API Constant for XLink
 * @type int 
 */
MasterQuery.API_XLINK             = 11;
/**
 * LexisNexis API Constant for XLink Seisint
 * @type int
 */ 
MasterQuery.API_XLINK_SEISINT      = 12;
/**
 * @type int 
 */
MasterQuery.API_DOSSIER_FORMS      = 13;

/**
 * Constant casts into v1_search with nexis searchform verb.
 * @type int 
 */
MasterQuery.API_NEXIS_SEARCHFORM   = 14;

/**
 * Constants for LNDB IA
 */
MasterQuery.API_IA_LNDB_ACTIVATION = 15;

MasterQuery.API_IA_LNDB_LOGOUT     = 16;

MasterQuery.API_IA_LNDB_LOGIN      = 17;

/**
 * LexisNexis API Constant for XLink Seisint
 * @type int
 */ 
MasterQuery.API_XLINK_PUBREC = 18;

/**
 * LexisNexis API Constant for XLink Seisint
 * @type int
 */ 
MasterQuery.API_URL_API_PUBREC      = 19;


/**
 * @type int
 */
MasterQuery.DEFAULT_API = MasterQuery.API_XLINK;

/**
 * The version number of the API
 * @type long
 */
MasterQuery.version = 1.0;

/**
 * The name of the API
 * @type String
 */
MasterQuery.name = "MasterQuery";

/**
 * The base URL location for the library
 * @type String
 */
MasterQuery.baseURL = "/clients/controls/MasterQuery/";


//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// Accessors


/**
 * Returns the protocol being used for the query
 *
 * @type String
 */
MasterQuery.prototype.getProtocol = function()
{
	return this.protocol;
}

/**
 * Sets the protocol being used for the query
 * @param {String}
 */
MasterQuery.prototype.setProtocol = function(strProtocol)
{
	switch(strProtocol)
	{
		case "http":
		case "http:":
			this.protocol = "http:";
			break;
		case "https":
		case "https:":
			this.protocol = "https:";
			break;
	}
}

/**
 * Returns the domain set for the query, if there is one. 
 * This mainly applies for XLink, which sometimes needs to
 * be called from several different domains because of cookie
 * and zone issues. 
 *
 * @return the domain being used for the object
 * @type String
 */
MasterQuery.prototype.getDomain = function()
{
	return this.domain;
}

/** 
 * Sets the domain set for the query, if there is one. 
 * This mainly applies for XLink, which sometimes needs to
 * be called from several different domains because of cookie
 * and zone issues. 
 * 
 * @param {String}
 */
MasterQuery.prototype.setDomain = function(strDomain)
{
	if ((strDomain.indexOf("exis.com") != -1) || (strDomain.indexOf("exis2.com") != -1))
	{
		this.domain = strDomain;
		return;
	}
	var re = /[01][01][01][01]/g;

	if (strDomain.match(re)) {
		this.domain = strDomain;
	}
}


/**
 * Returns the integer representing the API being used.
 *
 * @type int
 */
MasterQuery.prototype.getAPI = function()
{
	return this.api;
}

/**
 * Sets the integer representing the API being used.
 *
 * @param {String}
 */
MasterQuery.prototype.setAPI = function(intAPI)
{
	intAPI = parseInt(intAPI, 10);
	this.api = intAPI;
}

/**
 * Gets the query.
 *
 * @type String
 */
MasterQuery.prototype.getSearch = function()
{
	return this.search;
}

/**
 * Sets the LN query
 *
 * @param {String}
 */
MasterQuery.prototype.setSearch = function(strSearch)
{
	this.search = strSearch;
}

/**
 * Gets the value of searchtype.
 *
 * @type String
 */
MasterQuery.prototype.getSearchtype = function()
{
	return this.searchtype;
}

/**
 * The searchtype to use.  get for both xlink and CUIBuilder.  In the case of 
 * CUIBuilder, citation is eliminated and case is passed with setSearch().
 * @param {String}
 */
MasterQuery.prototype.setSearchtype = function(strSearchtype)
{

	this.searchtype = strSearchtype;
}

/**
 * Gets the value of TOCTarget.
 *
 * @type String
 */
MasterQuery.prototype.getTOCTarget = function()
{
	return this.TOCTarget;
}

/**
 * The value of "target" to be used to access tocs.  get for both xlink. 
 * @param {String}
 */
MasterQuery.prototype.setTOCTarget = function(strTOCTarget)
{

	this.TOCTarget = strTOCTarget;
}

/**
 * Gets the value of the source.
 *
 * @type String
 */
MasterQuery.prototype.getSource = function()
{
	return this.source;
}

/**
 * The source(s) to be used.
 * @param {String}
 */
MasterQuery.prototype.setSource = function(strSource)
{
	this.source = strSource.toUpperCase();
}

// DATE METHODS

/**
 * Gets the value of relativedate.
 *
 * @type String
 */
MasterQuery.prototype.getAfter = function()
{
	return this.after;
}

/**
 * The relativedate value to be used.  
 *
 * This method handles SmartLink (1:WK) and XLink style (previous_3_days) 
 * relative dates and translates all of them to SmartLink format.
 * @param {String}
 */
MasterQuery.prototype.setAfter = function(strAfter)
{
	// alert(strAfter)
	this.after = LNParser.parseAfter(strAfter)
}

/**
 * Gets the value of fromDate.
 *
 * @type String
 */
MasterQuery.prototype.getFromDate = function()
{
	return this.fromDate;
}

/**
 * fromDate to be appended to search string.
 * @param {String}
 */
MasterQuery.prototype.setFromDate = function(strFromDate)
{
	this.fromDate = DateUtil.parse(strFromDate);
}

/**
 * Gets the value of toDate.
 *
 * @type String
 */
MasterQuery.prototype.getToDate = function()
{
	return this.toDate;
}

/**
 * toDate to be appended to search string.
 * @param {String}
 */
MasterQuery.prototype.setToDate = function(strToDate)
{
	this.toDate = DateUtil.parse(strToDate);
}

/**
 * Gets the value of client.
 *
 * @type String
 */
MasterQuery.prototype.getClient = function()
{
  return this.client;
}

/**
 * Sets the client ID.
 * @param {String}
 */
MasterQuery.prototype.setClient = function(strClient)
{
  this.client = strClient;
}

/**
 * Gets the value of maxDocs.
 *
 * @type int
 */
MasterQuery.prototype.getMaxdocs = function()
{
  return this.maxdocs;
}

/**
 * Sets the number of documents to return.
 * @param {String}
 */
MasterQuery.prototype.setMaxdocs = function(intMaxdocs)
{
  intMaxdocs = parseInt(intMaxdocs, 10);
  if (intMaxdocs > 0)
  {
    this.maxdocs = intMaxdocs;
  }
}

/**
 * Gets the menu.
 *
 * @type String
 */
MasterQuery.prototype.getMenu = function()
{
	return this.menu;
}

/**
 * Sets the customer menu.
 * @param {String}
 */
MasterQuery.prototype.setMenu = function(strMenu)
{
	this.menu = strMenu;  
}

/**
 * Gets the OriginationCode.
 *
 * @type String
 */
MasterQuery.prototype.getOriginationCode = function()
{
	return this.originationCode;
}

/**
 * Sets the OriginationCode.
 * @param {String}
 */
MasterQuery.prototype.setOriginationCode = function(strOriginationCode)
{
	this.originationCode = strOriginationCode;  
}

/**
 * Gets the value of sort.
 *
 * @type String
 */
MasterQuery.prototype.getSort = function()
{
	return this.sort;
}

/**
 * Sets the sort order.
 * @param {String}
 */
MasterQuery.prototype.setSort = function(strSort)
{
  this.sort = strSort;  
}

/**
 * Gets the UID value.
 *
 * @type String
 */
MasterQuery.prototype.getUID = function()
{
  return this.uid;
}

/**
 * Sets the user ID.
 * @param {String}
 */
MasterQuery.prototype.setUID = function(strUID)
{
  this.uid = strUID;  
}

/**
 * Gets the PWD.
 *
 * @type String
 */
MasterQuery.prototype.getPWD = function()
{
  return this.pwd;
}

/**
 * Sets the PWD.
 * @param {String}
 */
MasterQuery.prototype.setPWD = function(strPWD)
{
  this.pwd = strPWD;  
}

/**
 * Gets the zone value.
 *
 * @type String
 */
MasterQuery.prototype.getZone = function()
{
  return this.zone;
}

/**
 * Sets the zone.
 * @type String
 */
MasterQuery.prototype.setZone = function(strZone)
{
  this.zone = strZone;  
}

//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// Target Form Methods

/**
 * Returns the method that the internal post form will be used.
 * This is an internal method used by the implementors.
 *
 * @type String
 */
MasterQuery.prototype.getMethod = function()
{
  return this.method;
}

/**
 * Sets the method that the internal post form will be used.
 * This is an internal method used by the implementors.
 *
 * @param {String}
 */
MasterQuery.prototype.setMethod = function(strMethod)
{
  this.method = strMethod;  
}

/**
 * Used to override the action for the MQ object. 
 * 
 * @type String
 */
MasterQuery.prototype.getOverride = function()
{
  return this.override;
}

/**
 * Used to override the action for the MQ object.
 *
 * @param {String}
 */
MasterQuery.prototype.setOverride = function(strOverride)
{
  this.override = strOverride;  
}

/**
 * Returns the window target used by the internet MasterQuery form.
 * 
 * @type String
 */
MasterQuery.prototype.getTarget = function()
{
  return this.target;
}

/**
 * Sets the window target used by the internet MasterQuery form.
 * 
 * @param {String}
 */
MasterQuery.prototype.setTarget = function(strTarget)
{
	this.target = strTarget;  
}

/**
 * Gets the Auth Token.
 *
 * @type String
 */
MasterQuery.prototype.getAuthToken = function()
{
	return this.authToken;
}

/**
 * Sets the OriginationCode.
 * @param {String}
 */
MasterQuery.prototype.setAuthToken = function(strAuthToken)
{
	this.authToken = strAuthToken;  
}

//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// METHODS

/**
 * Generic method for getting a MasterQuery value. 
 * return the value of the key passed in
 * @param {String} The key for the value to be returned
 */
MasterQuery.prototype.get = function(strParam)
{
	if (MasterQuery._isStandardField(strParam))
	{
		return this[strParam];
	}
	else
	{
		 return this["c_" + strParam];
	}
};

/**
 * Generic method for setting a MasterQuery value. 
 * For standard MasterQuery values set or the specific setter can be
 * used interchangably.
 *
 * Much of the headache behind this is to deal with the debug window. 
 * @param {String} The key for the value to be set
 * @param {String} The value to be set
 */
MasterQuery.prototype.set = function(strParam, strValue)
{
/*
 * NOTE: Adding a new MQ field:
 *     1) create the getter and accessor for the parameter
 *     2) add it to getMQFieldNames list
 *     3) If hidden add it to getAdditionalFields() hidden switch statement
 *     4) add to set switch statement
 *     5) add to _isStandardField
 */
 
	var myRegExp = /^c_/;
	if (myRegExp.test(strParam))
	{
		strParam = strParam.substring(2);
	}
 
	switch(strParam.toLowerCase())
	{
		case "":
			break;
		case "api":
			this.setAPI(strValue)
			break;
		case "search":
		case "query":
		case "searchterm":
		case "sr":
			this.setSearch(strValue);
			break;
		case "name":
			if (this.api == MasterQuery.API_URL_API)
			{
				this.set("nm", strValue);
			} else {
				this.setSearch(strValue);
			}
			break;
		case "source":
		case "src":
			this.setSource(strValue);
			break;
		case "searchtype":
		case "stp":
			this.setSearchtype(strValue);
			break;
		case "relativedate":
		case "after":
		case "daterelative":
			this.setAfter(strValue);
			break;
		case "client":
		case "clientid":
		case "pi":
			this.setClient(strValue);
			break;
		case "domain":
			this.setDomain(strValue);
			break;
		case "maxdocs":
		case "limit":
			this.setMaxdocs(strValue);
			break;
		case "menu":
		case "_menu":
			this.setMenu(strValue);
			break;
		case "method":
			this.setMethod(strValue);
			break;
		case "originationcode":
		case "origination_code":
		case "origincode":
			this.setOriginationCode(strValue);
			break;	
		case "override":
			this.setOverride(strValue);
			break;
		case "protocol":
			this.setProtocol(strValue);
			break;
		case "newsortmode":
		case "sortby":
			this.setSort(strValue);
			break;
		case "target":
			this.setTarget(strValue);
			break;
		case "user_id":
		case "uid":
			this.setUID(strValue);
			break;
		case "password":
		case "pwd":
		case "psw":
			this.setPWD(strValue);
			break;
		case "zone":
			this.setZone(strValue);
			break;
		case "company":
			if (this.api == MasterQuery.API_V1_SEARCH) 
			{
				if (Truth.isTrue(strValue)) 
				{
					this.setSearch("company" + QueryUtil.segment(strValue));
				}
				break;
			}
	    case "token":
	    case "uistoken":
	        this.setAuthToken(strValue);
	        break;
		default:
			if (strValue == "")
			{
				this["c_" + strParam] = null;
			}
			else
			{
				this["c_" + strParam] = strValue;
			}
	}

};

/**
 * 
 * 
 * @private
 * @param {String}
 * @return is the field standard to MasterQuery
 * @type boolean 
 */
MasterQuery._isStandardField = function(strParam)
{
	switch(strParam)
	{
		case "api":
		case "search":
		case "searchtype":
		case "source":
		case "after":
		case "fromDate":
		case "toDate":
		case "client":
		case "maxdocs":
		case "menu":
		case "originationCode":
		case "TOCTarget":
		case "sort":
		case "uid":
		case "pwd":
		case "zone":
		case "target":
		case "method":
		case "domain":
		case "protocol":
		case "override":
		case "authToken":
			return true;
			break;
	} 
	return false;
};

/**
 *
 * @param {boolean} optional value that if true disables the debug window.
 * @private
 */ 
MasterQuery.prototype.submit = function(forceNoDebug, OverrideWindowProps)
{
    var type = "regular";
    if (arguments.length > 0)
    {
        if (arguments[0].isAuthObject)
            type="auth";
	}
	if (type == "auth")
	    this.authSubmit(arguments[0]);
	else
        SearchImplementor.go(this, forceNoDebug, OverrideWindowProps);
};

/**
 * Displays all of the values in the MasterQuery object.
 * @type String 
 */
MasterQuery.prototype.toString = function()
{

	var s = "MasterQuery\n";
	if (this.api)             s += "    API: " + LNParser.getAPIName(this.api) + "\n";
	if (this.search)          s += "    SEARCH: " + this.search + "\n";
	if (this.searchtype)      s += "    SEARCH TYPE: " + this.searchtype + "\n";
	if (this.source)          s += "    SOURCE: " + this.source + "\n";
	if (this.after)           s += "    AFTER: " + this.after + "\n";
	if (this.fromDate)        s += "    FROM: " + this.fromDate + "\n";
	if (this.toDate)          s += "    TO: " + this.toDate + "\n";
	if (this.client)          s += "    CLIENT: " + this.client + "\n";
	if (this.maxdocs)         s += "    MAX DOCS: " + this.maxdocs + "\n";
	if (this.menu)            s += "    MENU: " + this.menu + "\n";
	if (this.originationCode) s += "    ORIGINATION_CODE: " + this.originationCode + "\n";
	if (this.sort)            s += "    SORT: " + this.sort + "\n";
	if (this.uid)             s += "    UID: " + this.uid + "\n";
	if (this.pwd)             s += "    PWD: ********\n";
	if (this.zone)            s += "    ZONE: " + this.zone + "\n";
	if (this.domain)          s += "    DOMAIN: " + this.domain + "\n";
	if (this.target)          s += "    TARGET: " + this.target + "\n";
	if (this.TOCTarget)       s += "    TOCTARGET: " + this.TOCTarget + "\n";
	if (this.method)          s += "    METHOD: " + this.method + "\n";
	if (this.override)        s += "    OVERRIDE: " + this.override + "\n";

	for (var i in this) {
		val = this[i];
		switch (typeof val) {
			case ("string"):
				if (/^c_/.test(i)) s += "    " + i.substr(2).toUpperCase() + ": " + val + "\n";
				break;
			default:
				break;
		}
		
	}

	return s;
};

MasterQuery.getEnvironment = function()
{
    var curDomain;
    curDomain = document.domain;
    curDomain = curDomain.toLowerCase();
    if (curDomain.indexOf("cert") != -1)
        return "CERT";
    else if (curDomain.indexOf("csintdev") != -1)
        return "CSINTDEV";
    else if (curDomain.indexOf("csint") != -1)
        return "CSINT";
    else
        return "PROD";
}

/**
 * Sets the user id and password which are pulled from the auth db.
 * authObject Parameters:
 *      siteID:                 The cui's site encrypted id number. ie. "1ce5ecc8ab642ac0"
 *      authType:               Determines whether the auth info is selected by ip address or by id name. 
 *                              Sample Inputs:
 *                                  "ip"
 *                                  "name"
 *      IDName:                 If the authType is "name" then the name to be selected must be passed.
 *      devOverride:            By default, pages in dev select the dev id instead of the prod id.  Passing "true" in this
 *                              parameter will override that functionality and always select the prod id.
 *      isCert:                 Returns cert id/pwd
 *      forceNoDebug:           Parameter passed through to submit function
 *      OverrideWindowProps:    Parameter passed through to submit function
 *      IDParameterName:        Determins parameter name used for ID
 *      PWDParameterName:       Determines parameter name used for Password
 */
MasterQuery.prototype.authSubmit = function(authObject)
{
    var siteID, authType, IDName, devOverride, isCert, forceNoDebug, OverrideWindowProps, IDParameterName, PWDParameterName;
    
    siteID = authObject.siteID;
    authType = authObject.authType.toLowerCase();
    IDName = authObject.IDName;
    devOverride = authObject.devOverride;
    isCert = authObject.isCert;
    forceNoDebug = authObject.forceNoDebug;
    OverrideWindowProps = authObject.OverrideWindowProps;
    IDParameterName = authObject.IDParameterName;
    PWDParameterName = authObject.PWDParameterName;

    if (siteID == "")
    {
        if (isDev())
            alert("Dev Alert:\nNo Site ID passed.");
        return false;
    }

    if (authType == "")
    {
        if (isDev())
            alert("Dev Alert:\nNo Auth Type passed.");
        return false;
    }
        
    if ((authType == "name") && (IDName == ""))
    {        
        if (isDev())
            alert("Dev Alert:\nNo ID Name passed.");
        return false;
    }
    
	if (devOverride != true)
		devOverride = false;
		
	var MQObj = this;
	var xmlObj = null;
	
    if(window.ActiveXObject)
    {   
        try
        {
            xmlObj = new ActiveXObject("Msxml2.XMLHTTP");            
        }
        catch(e)
        {
            xmlObj = new ActiveXObject("Microsoft.XMLHTTP");            
        }
    }    
    else if(window.XMLHttpRequest)
    {
        xmlObj = new XMLHttpRequest();        
    } else
    {
        return false;
    }

	xmlObj.onreadystatechange = function()
	{
		if(xmlObj.readyState == 4)
		{
			var temp, UID, PWD;
			temp = xmlObj.responseText;
			temp = temp.split(" ");
			UID = temp[0]
			PWD = temp[1];
			if (PWD == undefined)
				PWD = "";
			
			if(IDParameterName == "")
    			MQObj.uid = UID;
    		else
    		    eval("MQObj." + IDParameterName + " = UID");
    		    
			if(PWDParameterName == "")
    			MQObj.pwd = PWD;
    		else
    		    eval("MQObj." + PWDParameterName + " = PWD");
    		    
			MQObj.submit(forceNoDebug, OverrideWindowProps);
			return true;
		}
	}
	var file = "/clients/controls/auth/authHelper.asp";
	file = file + "?siteID=" + siteID + "&authType=" + authType + "&IDName=" + IDName + "&devOverride=" + devOverride + "&isCert=" + isCert;
	xmlObj.open ('GET', file, true);
	xmlObj.send ('');
	return true;
};

function authObject()
{
    this.isAuthObject = true;
    this.siteID = "";
    this.authType = "";
    this.IDName = "";
    this.devOverride = false;  
    this.isCert = false;  
    this.forceNoDebug = "";
    this.OverrideWindowProps = "";
    this.IDParameterName = "";
    this.PWDParameterName = "";
}

authObject.prototype.setSiteID = function(id)
{
	this.siteID = id;
}
authObject.prototype.getSiteID = function()
{
	return this.siteID;
}

authObject.prototype.setAuthType = function(type)
{
	this.authType = type;
}
authObject.prototype.getAuthType = function()
{
	return this.authType;
}

authObject.prototype.setIDName = function(IDName)
{
	this.IDName = IDName;
}
authObject.prototype.getIDName = function()
{
	return this.IDName;
}

authObject.prototype.setDevOverride = function(devOverride)
{
	this.devOverride = devOverride;
}
authObject.prototype.getDevOverride = function()
{
	return this.devOverride;
}

authObject.prototype.setIsCert = function(isCert)
{
	this.isCert = isCert;
}
authObject.prototype.getIsCert = function()
{
	return this.isCert;
}

authObject.prototype.setForceNoDebug = function(forceNoDebug)
{
	this.forceNoDebug = forceNoDebug;
}
authObject.prototype.getForceNoDebug = function()
{
	return this.forceNoDebug;
}

authObject.prototype.setOverrideWindowProps = function(OverrideWindowProps)
{
	this.OverrideWindowProps = OverrideWindowProps;
}
authObject.prototype.getOverrideWindowProps = function()
{
	return this.OverrideWindowProps;
}

authObject.prototype.setIDParameterName = function(IDParameterName)
{
	this.IDParameterName = IDParameterName;
}
authObject.prototype.getIDParameterName = function()
{
	return this.IDParameterName;
}

authObject.prototype.setPWDParameterName = function(PWDParameterName)
{
	this.PWDParameterName = PWDParameterName;
}
authObject.prototype.getPWDParameterName = function()
{
	return this.PWDParameterName;
}/*
Copyright (c) 2005 JSON.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The Software shall be used for Good, not Evil.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

http://www.crockford.com/JSON/js.html
*/

var JSON = {
    org: 'http://www.JSON.org',
    copyright: '(c)2005 JSON.org',
    license: 'http://www.crockford.com/JSON/license.html',
    
    stringify: function (arg) {
        var c, i, l, s = '', v;

        switch (typeof arg) {
        case 'object':
            if (arg) {
                if (arg.constructor == Array) {
                    for (i = 0; i < arg.length; ++i) {
                        v = this.stringify(arg[i]);
                        if (s) {
                            s += ',';
                        }
                        s += v;
                    }
                    return '[' + s + ']';
                } else if (typeof arg.toString != 'undefined') {
                    for (i in arg) {
                        v = arg[i];
                        if (typeof v != 'undefined' && typeof v != 'function') {
                            v = this.stringify(v);
                            if (s) {
                                s += ',';
                            }
                            s += this.stringify(i) + ':' + v;
                        }
                    }
                    return '{' + s + '}';
                }
            }
            return 'null';
        case 'number':
            return isFinite(arg) ? String(arg) : 'null';
        case 'string':
            l = arg.length;
            s = '"';
            for (i = 0; i < l; i += 1) {
                c = arg.charAt(i);
                if (c >= ' ') {
                    if (c == '\\' || c == '"') {
                        s += '\\';
                    }
                    s += c;
                } else {
                    switch (c) {
                        case '\b':
                            s += '\\b';
                            break;
                        case '\f':
                            s += '\\f';
                            break;
                        case '\n':
                            s += '\\n';
                            break;
                        case '\r':
                            s += '\\r';
                            break;
                        case '\t':
                            s += '\\t';
                            break;
                        default:
                            c = c.charCodeAt();
                            s += '\\u00' + Math.floor(c / 16).toString(16) +
                                (c % 16).toString(16);
                    }
                }
            }
            return s + '"';
        case 'boolean':
            return String(arg);
        default:
            return 'null';
        }
    },
    parse: function (text) {
        var at = 0;
        var ch = ' ';

        function error(m) {
            throw {
                name: 'JSONError',
                message: m,
                at: at - 1,
                text: text
            };
        }

        function next() {
            ch = text.charAt(at);
            at += 1;
            return ch;
        }

        function white() {
            while (ch) {
                if (ch <= ' ') {
                    next();
                } else if (ch == '/') {
                    switch (next()) {
                        case '/':
                            while (next() && ch != '\n' && ch != '\r') {}
                            break;
                        case '*':
                            next();
                            for (;;) {
                                if (ch) {
                                    if (ch == '*') {
                                        if (next() == '/') {
                                            next();
                                            break;
                                        }
                                    } else {
                                        next();
                                    }
                                } else {
                                    error("Unterminated comment");
                                }
                            }
                            break;
                        default:
                            error("Syntax error");
                    }
                } else {
                    break;
                }
            }
        }
        


        function string() {
            var i, s = '', t, u;

            if (ch == '"') {
outer:          while (next()) {
                    if (ch == '"') {
                        next();
                        return s;
                    } else if (ch == '\\') {
                        switch (next()) {
                        case 'b':
                            s += '\b';
                            break;
                        case 'f':
                            s += '\f';
                            break;
                        case 'n':
                            s += '\n';
                            break;
                        case 'r':
                            s += '\r';
                            break;
                        case 't':
                            s += '\t';
                            break;
                        case 'u':
                            u = 0;
                            for (i = 0; i < 4; i += 1) {
                                t = parseInt(next(), 16);
                                if (!isFinite(t)) {
                                    break outer;
                                }
                                u = u * 16 + t;
                            }
                            s += String.fromCharCode(u);
                            break;
                        default:
                            s += ch;
                        }
                    } else {
                        s += ch;
                    }
                }
            }
            error("Bad string");
        }

        function array() {
            var a = [];

            if (ch == '[') {
                next();
                white();
                if (ch == ']') {
                    next();
                    return a;
                }
                while (ch) {
                    // a.push(value());
                    a[a.length] = value();
                   
                    white();
                    if (ch == ']') {
                        next();
                        return a;
                    } else if (ch != ',') {
                        break;
                    }
                    next();
                    white();
                }
            }
            error("Bad array");
        }

        function object() {
            var k, o = {};

            if (ch == '{') {
                next();
                white();
                if (ch == '}') {
                    next();
                    return o;
                }
                while (ch) {
                    k = string();
                    white();
                    if (ch != ':') {
                        break;
                    }
                    next();
                    o[k] = value();
                    white();
                    if (ch == '}') {
                        next();
                        return o;
                    } else if (ch != ',') {
                        break;
                    }
                    next();
                    white();
                }
            }
            error("Bad object");
        }

        function number() {
            var n = '', v;

            if (ch == '-') {
                n = '-';
                next();
            }
            while (ch >= '0' && ch <= '9') {
                n += ch;
                next();
            }
            if (ch == '.') {
                n += '.';
                while (next() && ch >= '0' && ch <= '9') {
                    n += ch;
                }
            }
            v = +n;
            if (!isFinite(v)) {
                error("Bad number");
            } else {
                return v;
            }
        }

        function word() {
            switch (ch) {
                case 't':
                    if (next() == 'r' && next() == 'u' && next() == 'e') {
                        next();
                        return true;
                    }
                    break;
                case 'f':
                    if (next() == 'a' && next() == 'l' && next() == 's' &&
                            next() == 'e') {
                        next();
                        return false;
                    }
                    break;
                case 'n':
                    if (next() == 'u' && next() == 'l' && next() == 'l') {
                        next();
                        return null;
                    }
                    break;
            }
            error("Syntax error");
        }

        function value() {
            white();
            switch (ch) {
                case '{':
                    return object();
                case '[':
                    return array();
                case '"':
                    return string();
                case '-':
                    return number();
                default:
                    return ch >= '0' && ch <= '9' ? number() : word();
            }
        }

        return value();
    }
};
/**
 * @class Static Class for parsing LexisNexis API data and turning it into MasterQuery Objects.
 * <br /><br /> 
 * <b>	EXAMPLES:</b><br /> 
<dl>
	<dt>{@link #propertyFactory PROPERTY FACTORY}</dt>
	<dd><pre>var chunnel = LNParser.propertyFactory('properties.txt');</pre></dd>
	<dt>{@link #queryStringFactory QUERY STRING}</dt>
	<dd><pre>var chunnel = LNParser.queryStringFactory("client=FEDTAX02&source=718dis;dguide&search=file-name(fedday)&view=full&ORIGINATION_CODE=00004");
   chunnel.submit();</pre></dd>
	<dt>{@link #factory EMBEDDED IN LINK}</dt>
	<dd><pre>&lt;a href=&quot;http://www.lexis.com/research/xlink?client=FEDTAX02&source=718dis;dguide&search=file-name(fedday)&view=full&ORIGINATION_CODE=00004&quot; 
   onclick=&quot;LNParser.factory(this).submit(); return false;&quot;&gt;link&lt;/a&gt;</pre>
		You can also override any of the links value by passing in a properties file:
		<pre>&lt;a href=&quot;http://www.lexis.com/research/xlink?client=FEDTAX02&source=718dis;dguide&search=file-name(fedday)&view=full&ORIGINATION_CODE=00004&quot; 
   onclick=&quot;LNParser.propertyFactory('properties.txt', LNParser.factory(this)).submit(); return false;&quot;&gt;link loader&lt;/a&gt;</pre>
	<br />
	</dd>
</dl>
 
 * @author Christopher Baker <Christopher.Baker@lexisnexis.com>
 * @version 0.1 
 * @constructor
 */
function LNParser()
{
	throw new Error("LNParser is a static class. Do not instantiate.");
}

/**
 * Regular expression for stripping off the query string from a URL
 * @type String
 */ 
LNParser.queryStringRE  = /\?(.+)$/;

/**
 * Factory method that takes an Anchor Object with a L/N Query as the HREF or
 * a L/N link string and returns a MasterQuery object based upon it. 
 *
 * @return A MasterQuery Object based upon the link
 * @param {Object} 
 * @type MasterQuery
 */
LNParser.factory = function(link, props)
{
	var strurl;
	var lnAPI;
	var target = "";
	// Check to see if it is an HREF String or an ANCHOR tag that is passed in.
	if (typeof link  == "object")
	{
		/* Might be useful later for adding web form parsing. 
		// are we a web form
			if (link.action) 
			{
				with (myForm)
				{
					strurl = action
					//check for text boxes
					for (elem = 0; elem < elements.length; elem++)
					{
					}
				}
			}*/
		
		strurl = link.href;
		target = link.target;
	}
	else
	{
		strurl = link;
	}
	
	lnAPI = LNParser.getAPI(strurl);

	// Set default API to XLink
	if (lnAPI === null)
	{
		lnAPI == MasterQuery.API_XLINK;
	}
	
	var m = strurl.match(LNParser.queryStringRE);
	
	var chunnel = new MasterQuery(lnAPI);
	
	chunnel.setTarget(target);
	
	if (props)
	{
		try
		{
			// if it's a Properties Object, get the values
			props = props.getProperties();
		}
		catch(e)
		{
			// otherwise do nothing. 
		}
		
		try{
			for (var prop in props) 
			{	
				chunnel.set(prop, props[prop]);
			}
		}
		catch(e)
		{
			if (isDev())
				alert(e.message)
		}		
	}
	
	if (strurl.indexOf("https://") != -1) 
	{
		chunnel.isUsingSSL = true;
	}
	
	/*
	doesn't seem to be working
	// Determine the domain that is being used.
	// For xlink to maintain 
	var mm = strurl.match(new RegExp("^https?:\/\/([A-Za-z]*\.?lexisnexis|lexis-nexis|lexis|nexis\.com)", "i"))
	
	if (mm) 
	{
		chunnel.setDomain(m[1]);
	}
	*/
	
	if (lnAPI === MasterQuery.API_DOSSIER)
	{
		chunnel.set("verb", "accessGW");
		chunnel.set("gw", "FC");
		chunnel.set("nm", chunnel.get("name"));
	}
	
	// http://www.lexisnexis.com/api.universe/v1_dossier_launch_forms?ORIGINATION_CODE=00004&prod=CD&host=nexis_com_r2&searchType=advancedFind

	chunnel = LNParser.queryStringFactory(m[1], chunnel);

	if (lnAPI === MasterQuery.API_DOSSIER_FORMS)
	{
		// http://www.lexisnexis.com/api.universe/v1_dossier_launch_forms?prod=CD
		// http://www.lexisnexis.com/api.universe/v1_dossier_launch_forms?prod=ID
		// http://www.lexisnexis.com/api.universe/v1_dossier_launch_forms?prod=CD&searchType=advancedFind
		// http://www.lexisnexis.com/api.universe/v1_dossier_launch_forms?prod=CD&searchType=quickFind
		
		chunnel.set("verb", "accessGW");
		
		if (chunnel.get("prod") == "ID") 
		{
			chunnel.set("gw", "FI");
		} 
		else 
		{
			if (chunnel.getSearchtype() == "quickFind")
			{
				chunnel.set("gw", "FC");
			} 
			else
			{
				chunnel.set("gw", "CL");
			} 
		}
	}

	

	return chunnel;

};

/**
 * Takes a querystring and returns a MasterQuery Object. If 
 * a MasterQuery Object is passed in as the second parameter
 * then the data is folded into that object. 
 *
 * See the overview for usage examples.
 *
 * @return A MasterQuery Object based upon the Query String
 * @param {String} A URL QueryString to be based
 * @param {MasterQuery} Optional MasterQuery Object for the values to be folded into
 * @type MasterQuery
 */ 
LNParser.queryStringFactory = function(queryString, chunnel)
{
	if (!chunnel)
	{
		chunnel = new MasterQuery();
	}
	var queryArray = queryString.split("&");
	for (var i = 0; i < queryArray.length; i++) 
	{		
		var sp = queryArray[i].split("=");
		var key = sp[0];
		var val = "";
        
        if (sp.length > 2)
        {
            for(var x = 2; x < sp.length; x++)
            {
                sp[1] = sp[1] + "=" + sp[x];
            }
        }
        
		try
		{
			if (sp[1]) val = decodeURIComponent(sp[1]);
		}
		catch(e)
		{
			try
			{
				if (sp[1]) val = unescape(sp[1]);
			}
			catch(e)
			{
				if (isDev())
				{
					prompt("",e.message)
				}
			}
		}
		
		if (key.toLowerCase() != "submit")
    		chunnel.set(key, val);
	}
	return chunnel;
};

/**
 * Takes a JSProperties Object and returns a MasterQuery Object.  If 
 * a MasterQuery Object is passed in as the second parameter
 * then the data is folded into that object.
 * <br /><br />
 * This method includes support for a special property value  
 * <tt>__TIME_DELAY__</tt>. Setting this property allows a developer
 * to override a specific value at a specific time. This allows you
 * to change from one API to another when the time is reached. 
 * <br /><br />
 * The format is Y:M:D:H:M:S;<i>key</i>;<i>value</i>
 * 
 * @return A MasterQuery Object based upon the properties file pased in
 * @param {Object} JSProperties Object or file name for the properties file.
 * @param {MasterQuery} Optional MasterQuery Object for the values to be folded into
 * @type MasterQuery
 */
LNParser.propertyFactory = function(props, chunnel)
{
	if (props)
	{
		if (typeof props == "string")
		{
			props = new JSProperties(props);
		}
	}
	else
	{
		// Otherwise create a default JSProperties object
		props = new JSProperties();
	}
	
	// Create the object that will be if it isn't already passed in. 
	if (!chunnel) 
	{
		chunnel = new MasterQuery();
	}
	
	// Make sure that the var passed in is an object.
	if ((arguments.length > 0))
	{
		if (typeof arguments[0] == "object")
		{
			props = arguments[0];
		}
		else
		{
			props = new JSProperties(arguments[0]);
		}		
	}
	
	// Now punch in the properties that match the MQ object main fields
	var properties = props.getProperties();
	try{
		for (var prop in properties) 
		{	
			switch(prop)
			{
				case "__TIME_DELAY__":
					// format for the var split is date;varName;varValue
					var pOver = properties[prop].split(";");
					
					var dOver = pOver[0].split(":");
					
					// alert(dOver[0] + " " + dOver[1] + " " + dOver[2] + " " + dOver[3] + " " + dOver[4])
					
					//          new Date(aYear,    aMonth,   aDate,    anHour,   aMinute,  aSecond)
					var dDate = new Date(dOver[0], dOver[1] - 1, dOver[2], dOver[3], dOver[4], dOver[5]);
					
					dDate.setFullYear(dOver[0]);
					
					var currentDate = new Date();
					
					// alert(dDate + " " + currentDate);
					
					// prompt("", dDate.getTime() + " " + currentDate.getTime())
					
					if (dDate.getTime() < currentDate.getTime())
					{
						// alert()
						chunnel.set(pOver[1], pOver[2]);
					}
					break;
				default:
					chunnel.set(prop, properties[prop]);
					break;
			}
		}
	}
	catch(e)
	{
		if (isDev())
			alert(e.message)
	}
	
	return chunnel;
};

/** 
 * Returns the API being used by a specific LN link.
 * @param {String} QueryString to determine what L/N API is being used.
 * @type int
 */
LNParser.getAPI = function(strURL)
{
	if(strURL) 
	{ 
		strURL = strURL.toLowerCase(); 
	}
	else
	{
		return null;
	}
	
	if (strURL.lastIndexOf(".com/clients/cui/search.asp") != -1)
	{
		return MasterQuery.API_CUI_BUILDER;
	}
	else if (strURL.lastIndexOf(".com/clients/cuiint/search.asp") != -1)
	{
		return MasterQuery.API_CUI_INTERNATIONAL;
	}	
	else if ((strURL.lastIndexOf("lexis-nexis.com/professional") != -1) || (strURL.lastIndexOf("lexisnexis.com/professional") != -1))
	{
		return MasterQuery.API_PROFESSIONAL;
	}	
	else if ((strURL.lastIndexOf("lexisnexis.com/api.universe/v1_dossier_launch_results") != -1) || (strURL.lastIndexOf("lexis-nexis.com/api.universe/v1_dossier_launch_results") != -1))
	{
		return MasterQuery.API_DOSSIER;
	}
	else if ((strURL.lastIndexOf("lexisnexis.com/api.universe/v1_portfolio") != -1) || (strURL.lastIndexOf("lexis-nexis.com/api.universe/v1_portfolio") != -1))
	{
		return MasterQuery.API_V1_PORTFOLIO;
	}	
	else if (strURL.lastIndexOf("nexis.com/api.universe/v1_searchform") != -1)
	{
		return MasterQuery.API_V1_SEARCHFORM;
	}
	else if ((strURL.lastIndexOf("lexisnexis.com/api.universe/v1_search") != -1) || (strURL.lastIndexOf("lexis-nexis.com/api.universe/v1_search") != -1))
	{
		return MasterQuery.API_V1_SEARCH;
	}	
	else if ((strURL.lastIndexOf("nexis.com/api.universe/v1_snews") != -1) || (strURL.lastIndexOf("lexis-nexis.com/api.universe/v1_snews") != -1))
	{
		return MasterQuery.API_V1_SNEWS;
	}	
//	else if ((strURL.lastIndexOf("exis.com/xlink") != -1) || (strURL.lastIndexOf("exis.com/research/xlink" != -1)))
//	{
//		return MasterQuery.API_XLINK;
//	}
	
	// ADDED
	else if (strURL.lastIndexOf("nexis.com/api.universe/v1_dossier_launch_forms") != -1)
	{		 // http://www.lexis-nexis.com/api.universe/v1_dossier_launch_forms
		
		return MasterQuery.API_DOSSIER_FORMS;
	}
	else if (strURL.lastIndexOf("nexis.com/api.universe/search/searchform") != -1)
	{
		return MasterQuery.API_NEXIS_SEARCHFORM;
	}
	
	// ADDED for IA
	
	else if ((strURL.lastIndexOf("exis.com/auth/lnu/activate.asp") != -1) || (strURL.lastIndexOf("exis.com/auth/lnu/activateLexis.asp") != -1) || (strURL.lastIndexOf("exis.com/auth/lnu/activatenexis.asp") != -1) || (strURL.lastIndexOf("exis.com/auth/lnu/activatenexisorgid.asp") != -1))
	{
		return MasterQuery.API_IA_LNDB_ACTIVATION;
	}
	
	else if ((strURL.lastIndexOf("exis.com/auth/lnu/lckill.asp") != -1) || (strURL.lastIndexOf("exis.com/auth/lnu/nckill.asp") != -1) || (strURL.lastIndexOf("exis.com/auth/lnu/lnckill.asp") != -1))
	{
		return MasterQuery.API_IA_LNDB_LOGOUT;
	}
	
	else if (strURL.lastIndexOf("exis.com/auth/lnu/setCookie.asp") != -1)
	{
		return MasterQuery.API_IA_LNDB_LOGIN;
	}
	return null;
};



MasterQuery.API_IA_LNDB_LOGOUT = 16;

/**
 * Returns a human readable version of a LN Api names. Used for debugging window.
 * @param {int} QueryString to determine what L/N API is being used.
 * @type String
 */
LNParser.getAPIName = function(strAPI)
{
	switch(strAPI) 
	{
		case MasterQuery.API_CUI_BUILDER:
			return "CUI Builder";
			break;
		case MasterQuery.API_CUI_INTERNATIONAL:
			return "CUI International";
			break;
		case MasterQuery.API_DOSSIER:
			return "Dossier";
			break;
		case MasterQuery.API_DOSSIER_FORMS:
			return "Dossier Launch Forms";
			break;	
		case MasterQuery.API_GET_AND_PRINT:
			return "Get and Print";
			break;
		case MasterQuery.API_NEXIS_SEARCHFORM:
			return "Nexis Search Form";
			break;	
		case MasterQuery.API_PROFESSIONAL:
			return "Professional";
			break;
		case MasterQuery.API_URL_API:
			return "Rosetta";
			break;
		case MasterQuery.API_V1_PORTFOLIO:
			return "Smart Tools v1_portfolio";
			break;
		case MasterQuery.API_V1_SEARCH:
			return "Smart Tools v1_search";
			break;
		case MasterQuery.API_V1_SEARCHFORM:
			return "Smart Tools v1_searchform";
			break;
		case MasterQuery.API_V1_SNEWS:
			return "Smart Tools v1_snews";
			break;
		case MasterQuery.API_XLINK:
			return "XLink";
			break;
		case MasterQuery.API_XLINK_SEISINT:
			return "XLink Seisint";
			break;
		case MasterQuery.API_IA_LNDB_ACTIVATION:
			return "LNDB Instant Activation";
			break;
		case MasterQuery.API_IA_LNDB_LOGOUT:
			return "LNDB IA Logout";
			break;
		case MasterQuery.API_IA_LNDB_LOGIN:
			return "LNDB IA Login";
			break;
		case MasterQuery.API_XLINK_PUBREC:
			return "XLink Public Records";
			break;
		case MasterQuery.API_URL_API_PUBREC:
			return "Rosetta Public Records";
			break;

	}
	return "";
};

/** 
 * Parses various after/relative date values and returns an after value.
 * @param {String} Any relative date/after value
 * @type String 
 */
LNParser.parseAfter = function(strAfter)
{

	if (!Truth.isTrue(strAfter))
	{
		return "";
	}
		
	try
	{
		strAfter = strAfter.toUpperCase();
	}
	catch(e)
	{
		strAfter = strAfter.toString();
	}
	
	// /^\d+:DY|WK|MO|YR$/ 
	if (strAfter.search(/^\d+:(DY|WK|MO|YR)$/i) != -1)
	{
		return strAfter;
	}

	strAfter = strAfter.toLowerCase();

	switch(strAfter)
	{
		case "today":
			return "1:DY";
			break;
		case "this_week":
		case "previous_week":
			return "1:WK";
			break;
		case "this_month":
		case "previous_month":
			return  "1:MO";
			break;
		case "this_year":
		case "previous_year":
			return "1:YR";
			break;
	}

	if (strAfter.lastIndexOf("_") != -1)
	{	
		var relAr = strAfter.split("_");
		// The number for the relative date
		var relInt = relAr[1];
		// The type, such as days or weeks
		var relPeriod = relAr[2];
		
		if (relInt.search(/^\d+$/) == -1)
		{	
			return null;
		}

		switch(relPeriod)
		{
			case "days":
				return relInt + ":DY";
				break;
			case "weeks":
				return relInt + ":WK";
				break;
			case "months":
				return relInt + ":MO";
				break;
			case "years":
				return relInt + ":YR";
				break;
		}
	}
	return null;

};

/**
 * Takes a valid after date value and returns it in the relative date format
 * @param {String} After date value
 * @type String 
 */
LNParser.convertAfterToRelative = function(after)
{
	if (!Truth.isTrue(after))
	{
		return "";
	}
	
	var dArray = after.split(":")
	// The integer for the length
	var dInt = dArray[0];
	var dPeriod = dArray[1];
	
	switch(dPeriod)
	{
		case "DY":
			if (dInt == 1)
			{
				return "today";
			}
			return "previous_" + dInt + "_days";
			break;
		case "WK":
			if (dInt == 1)
			{
				return "previous_week";
			}
			return "previous_" + dInt + "_weeks";
			break;
		case "MO":
			if (dInt == 1)
			{
				return "previous_month";
			}
			return "previous_" + dInt + "_months";
			break;
		case "YR":
			if (dInt == 1)
			{
				return "previous_year";
			}
			return "previous_" + dInt + "_years";
			break;
	}
	return "";
};

/**
 * Takes a MasterQuery Object and converts any date properties to L/N Query syntax.
 * Used for implementors whose APIs don't support relative date paramaters.
 * @param {MasterQuery} 
 * @type MasterQuery
 */

LNParser.convertDateToQuery = function(mq, format)
{
	if (mq.after) 
	{
		var dRange     = mq.after.substring(0, mq.after.length - 3);
		var dRangeType = mq.after.substring(mq.after.length - 2);
		
		var theDate = new Date();
		var currDate = new Date();
		
		switch(dRangeType)
		{
			case "DY":
				theDate.setDate(theDate.getDate() - dRange);
				break;
			case "WK":
				theDate.setDate(theDate.getDate() - (dRange * 7));
				break;
			case "MO":
				theDate.setMonth(theDate.getMonth() - dRange);
				break;
			case "YR":
				theDate.setFullYear(theDate.getFullYear() - dRange);
				break;
		}
		var oneDay = 86400000;
		var dayDiff = Math.ceil((currDate.getTime()-theDate.getTime())/(oneDay));
        dayDiff = dayDiff + 1;
        
		var dStr = "date aft(%currdate-" + dayDiff + "%)";
		if((mq.get("adaption") == "uk") && ((mq.get("type") == "nexis") || (mq.get("type") == "business")))
		    dStr = "date aft(" + theDate.getDate() + "/" + (parseInt(theDate.getMonth())+parseInt("1")) + "/" + theDate.getFullYear() + ")";
		LNParser.foldIn(mq, dStr);
		mq.after = "";
	}
	else if (mq.fromDate && mq.toDate) 
	{
		var dStr = "date(geq (" + mq.fromDate + ") and leq (" + mq.toDate + "))";
		
		LNParser.foldIn(mq, dStr);
		mq.fromDate = "";
		mq.toDate = "";
		
	}
	else if (mq.fromDate) 
	{
		var dStr = "date(geq (" + mq.fromDate + ")";
		LNParser.foldIn(mq, dStr);
		
		mq.fromDate = "";
	}
	else if (mq.toDate) 
	{
		var dStr = "date(leq (" + mq.toDate + "))";
		LNParser.foldIn(mq, dStr);
		
		mq.toDate = "";
	}

	return mq;
};

/**
 * Method to fold in a LN Query version of a date. Determines if the
 * date should be at the beginning or the end of the query depending
 * upon if it has a NOT value in the Query. This is to avoid a bug
 * in certain LN APIs.
 * @param {MasterQuery} 
 * @param {String} Date String
 * @type MasterQuery
 */
LNParser.foldIn = function(mq, dStr)
{
	var searchIncludesNot = mq.search.match(new RegExp("NOT", "i"));
	
	if (mq.search) 
	{
		if (searchIncludesNot)
		{
			mq.search = dStr + " and " + mq.search;
		}
		else
		{
			mq.search =  mq.search + " and " + dStr;
		}
	}
	else
	{
		mq.search = dStr;
	}
	return mq;
};
/**
 * @class Static Class that acts as the traffic cop for MasterQuery Objects. Determines
 * where it goes and if there needs to be a debug window displayed.
 *
 * @author Christopher Baker <Christopher.Baker@lexisnexis.com>
 * @version 0.1 
 */

//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// CONSTANTS

var NEW_WINDOW_FEATURES = 'status=yes,resizable=yes,menubar=yes,scrollbars=yes,toolbar=yes,directories=yes,location=yes'

var searchImplementorCount = 0

/**
 * @constructor
 * @private
 */
function SearchImplementor()
{
	throw new Error("SearchImplementor is a static class. Do not instantiate.");
}

/**
 * Set to true to force a debug popup even in prod.
 */
SearchImplementor.debugOn = false;

/**
 * That action method. Should we do a popup, or assign the Object to an
 * implementor?
 */
SearchImplementor.go = function(mq, forceNoDebug)
{
	if (MasterQuery.NO_DEBUG) {
		forceNoDebug = true;
	}
	if (forceNoDebug)
	{
		SearchImplementor.assign(mq);
		return;
	}

	if (isDev() || SearchImplementor.debugOn)
	{
		SearchImplementor.popup(mq);
	}
	else
	{
		SearchImplementor.assign(mq);
	}
}

/**
 * Open up the debug popup window.
 */
SearchImplementor.popup = function(mq)
{
	newWindow = window.open("","_blank","status=no,left=0,top=0,height=420,width=540,scrollbars=yes");
	SearchImplementor.mqRef = mq;

    newWindow.document.write(SearchImplementor.getDebugPopupHMTL(mq));
    
    newWindow.document.close( ); // close layout stream
}

/**
 * Used to test if we can see the object
 */
SearchImplementor.BOOP = function()
{
	alert("BOOP!")
}

/**
 * Returns the HTML for the debug popup window.
 */
SearchImplementor.getDebugPopupHMTL = function(mq)
{
	var str = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">';
	str += '<html>\n';
	str += '<head>\n';
	str += '<title>Development Information: Master Query<\/title>\n';

	// Our stylesheet
	str += '<link href="';
	str += MasterQuery.baseURL
	str += 'debugWindow.css" rel="stylesheet" type="text\/css">\n';

	// our javascript files
	str += '<script type="text/javascript" language="javascript" src="';
	str += MasterQuery.baseURL
	str += 'MQInclude.asp"></script>\n';
	
	str += '<script type="text/javascript" language="javascript" src="';
	str += MasterQuery.baseURL
	str += 'MasterQueryDebug.js"></script>\n';
    str += '<script language=javascript>\n';
    str += 'var decode = false;\n';
    str += 'function toggleDecode(link)\n';
    str += '{//alert(document.body.clientHeight + " " + document.documentElement.clientHeight + " " + document.body.clientWidth + " " + document.documentElement.clientWidth);\n';
    //str += 'window.resize(document.body.clientHeight,document.body.clientWidth);\n'
    str += '    var ques = document.MasterQuerySearchImplementor.link.value.indexOf("?");\n';
    str += '    var url = document.MasterQuerySearchImplementor.link.value.slice(0,ques);\n';
    str += '    var queryString = document.MasterQuerySearchImplementor.link.value.slice(ques + 1);\n';
    str += '\n';
    str += '    if (decode == false)\n';
    str += '    {\n';
    str += '        document.MasterQuerySearchImplementor.link.value = url + "?" + decodeURIComponent(queryString).replace(/%3D/g, "=").replace(/%26/g, "&");\n';
    str += '        link.innerHTML = "<font color=black size=\'1\'>Reencode</font>";\n';
    str += '        decode = true;\n';
    str += '    } else\n';
    str += '    {\n';
    str += '        document.MasterQuerySearchImplementor.link.value = url + "?" + encodeURIComponent(queryString).replace(/%3D/g, "=").replace(/%26/g, "&");\n';
    str += '        link.innerHTML = "<font color=black size=\'1\'>Decode</font>";\n';
    str += '        decode = false;\n';
    str += '    }\n';
    str += '    return false;\n';
    str += '}\n';
    str += '</script>\n';
	str += '</head>\n';
	str += '<body onload="init();">';
	str += '<form action="/clients/controls/MasterQuery/test/testSearchImplementor.htm" onsubmit="callBack();" name="MasterQuerySearchImplementor" ID="Form1">';

	str += '<input type="hidden" name="__mqJsonStore__" value=\'' + escape(JSON.stringify(mq))  + '\'>\n'

	str += '<fieldset>\n';
	str += '<legend>\n';
	str += '					Development Information: MasterQuery<\/legend>\n';
	str += '<div class="sublegend">This development-only popup will not be displayed in production.';
	if (SearchImplementor.mqRef.uid != undefined)
    	str += '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" onclick="alert(\'Authentication Values:\\n\\nUser ID:    ' + SearchImplementor.mqRef.uid + '\\nPassword: ' + SearchImplementor.mqRef.pwd + '\');return false;"><font color=black>Show ID/PWD</font></a>';
	str += '<\/div>\n<br>\n';
	
	str += '<input type="submit" value="SUBMIT" id="smit" style="margin-left: 120px;" class="b">\n';
	str += '<input type="button" value="CANCEL" class="b" onclick="cancelPopup()">\n';
	str += '<input type="button" value="NO DEBUG" class="b" onclick="cancelPopup();window.opener.MasterQuery.NO_DEBUG = true">\n';
	str += '<br>\n';
	
	str += '<label for="search">QUERY:<\/label> \n';
	str += '<textarea id="search" name="search" rows="3" cols="40">\n';
	str += SearchImplementor.mqRef.getSearch()
	str += '<\/textarea>\n';
	str += '<br>\n';

	str += '<br>\n';
	str += '<div id="additionFields">\n';
	str += SearchImplementor.getAdditionalFields(mq);
	str += '<\/div>';
	str += '<font color=black size=1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Changes to Link box will not affect search.</font><br />\n';
	str += '<label for="link">LINK:<\/label> \n';
	str += '<input type="text" class="visible" id="link" name="link" value="' + SearchImplementor.getLink(mq) + '">\n';
	str += '<a href="#" onclick="return toggleDecode(this);"><font color=black size="1">Decode</font></a>';
	str += '<br>\n';


	str += '<label for="api">API:<\/label>\n';
	str += '<select name="api" id="api">\n';
	str += SearchImplementor.getAPIOptions(mq.getAPI())
	str += '<\/select>\n';
	str += '<br>\n';

	str += '<hr>\n';
	str += '<div class="debug">debug<\/div>\n';
	str += '<\/fieldset>\n';
	str += '<\/form>\n';
	str += '<\/body>\n';
	str += '<\/html>\n';
	return str;
}

SearchImplementor.getLink = function(mq)
{
	switch(mq.getAPI())
	{
		case 1:
		case 2:
			return CUIBuilderImp.getLink(CUIBuilderImp._preprocessor(mq))
			break;
		case 3:
			return DossierImp.getLink(DossierImp._preprocessor(mq));
			break;
		case 4:
			return GPImp.getLink(GPImp._preprocessor(mq));
			break;
		case 5:
			return LNProfImp.getLink(LNProfImp._preprocessor(mq));
			break;
		case 6:
			return UrlApiImp.getLink(UrlApiImp.preprocessor(mq));
			break;
		case 7:
		case 8:
		case 9:
		case 10:
		case 13:
		case 14:
			return V1SearchImp.getLink(V1SearchImp._preprocessor(mq));
			break;
		case 12:
			return SeisintImp.getLink(SeisintImp._preprocessor(mq));
			break;
		case 18:
			return XLinkPubRecImp.getLinkWithXML(XLinkPubRecImp._preprocessor(mq));
			break;
		case 19:
			return UrlApiPubRecImp.getLink(UrlApiPubRecImp.preprocessor(mq));
			break;

		case 11:
		default:
			return XLinkImp.getLink(XLinkImp._preprocessor(mq));
			break;
	}
	return XLinkImp.getLink(XLinkImp._preprocessor(mq))
}

/**
 * Gets all of the additional custom fields for the MasterQuery Object
 * and determines which ones to display.
 */
SearchImplementor.getAdditionalFields = function(mq)
{
	var fields = SearchImplementor.getMQFieldNames(mq);
	var html = "";

	for (var x = 0; x < fields.length; x++)
	{
		var val;
		if (mq[fields[x]]) { val = mq[fields[x]]; }
		else { val = mq.get(fields[x]); }
        
        if(fields[x] == "domain" && val == undefined)
            val = SearchImplementor.getLink(mq).split("/")[2];
		
		if (val !== null)
		{
			// var fieldName = "MQ" + fields[x];
			// var fieldName = fields[x];
			var fieldName = fields[x];

			var inputType  = "text"
			var inputLabel = '<label for="' +  fieldName + '">' + fields[x].toUpperCase() + ':</label>'
			var linefeed   = "<br clear='all'>";
			var cssClass   =  "visible"

			//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
			// SET DEBUG HIDDEN FIELDS HERE
			switch(fieldName)
			{
				case "method":
				case "target":
				case "override":
				case "protocol":
				case "lexislogo":
				case "lexislogo":
				case "interface":
				case "powernav":
				case "topframe":
				case "docinfo":
				case "mj":
				case "MIDDLEWARE_CODE":
				case "submit":
				case "uid":
				case "pwd":
					inputType = "hidden";
					cssClass  = "hidden";
					inputLabel = "";
					linefeed   = "";
			}

			html += inputLabel;
			html += '<input class="' + cssClass + '" type="' + inputType + '" name="' + fieldName + '" id="' + fieldName + '" value="' + val + '">' + linefeed;
		}
	}
	return html;
}

/**
 * Grabs the name for a specific field. Needed to avoid name collision with
 * core MasterQuery fields.
 */
SearchImplementor.getMQFieldNames = function(mq)
{
	//
	var fields = new Array("searchtype", "source", "after", "fromDate", "toDate", "client", "maxdocs", "menu", "sort","uid","pwd","zone", "originationCode", "target", "TOCTarget", "method", "protocol", "domain",  "override");
	var setArray = new Array()

	// Add existing standard fields
	for (var x = 0; x < fields.length; x++)
	{
		// if (mq[fields[x]] || mq[fields[x]] == "")
		if (mq[fields[x]] || fields[x] == "domain")
		{
			// setArray.push(fields[x])
			setArray[setArray.length] = fields[x];
		}
	}
	// Add custom SET fields
	for (var i in mq)
	{
		if (i.lastIndexOf("c_") == 0) {
			// setArray.push(i.substring(2));
			setArray[setArray.length] = i.substring(2);
		}
	}
	return setArray;
}

/**
 * Returns the API switcher dropdown for the debug popup.
 */
SearchImplementor.getAPIOptions = function(selected)
{
	var ret = ""
	for (var x = 1; x < 20; x++)
	{
		switch(x)
		{
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
			case 11:
			case 12:
			case 13:
			case 14:
			case 15:
			case 16:
			case 17:
			case 18:
			case 19:
				if (x == selected)
				{
					ret += '<option value="' + x + '" selected>' + LNParser.getAPIName(x) + '</option>\n';
				}
				else
				{
					ret += '<option value="' + x + '">' + LNParser.getAPIName(x) + '</option>\n';
				}
			break;
		}

	}
	return ret;
}

/**
 * Returns a DOM Option object
 * DEPRECATED
 */
SearchImplementor.getOption = function(newwin, winame, val)
{
	var dFormOption = newwin.document.createElement("option");
	dFormOption.name  = name
	dFormOption.value = name
	dFormOption.text = val
	return dFormOption
}

/**
 * Sends the MasterQuery Object to a specific implementor.
 */
SearchImplementor.assign = function(mq)
{
	switch(mq.getAPI())
	{
		case 1:
			CUIBuilderImp.submit(mq);
			break;
		case 2:
			CUIBuilderImp.submit(mq);
			// CUIIntBuilderImp(mq);
			break;
		case 3:
			// Add URL API vars
			DossierImp.submit(mq);
			break;
		case 4:
			GPImp.submit(mq);
			break;
		case 5:
			LNProfImp.submit(mq);
			break;
		case 6:
			UrlApiImp.submit(mq);
			break;
		case 7:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "v1_portfolio")
			}
			V1SearchImp.submit(mq);
			break;
		case 8:
			V1SearchImp.submit(mq);
			break;
		case 9:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "v1_searchform")
			}
			V1SearchImp.submit(mq);
			break;
		case 10:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "v1_snews")
			}
			V1SearchImp.submit(mq);
			break;
			
			break;
		case 12:
			// V1SearchImp.submit(mq);
			SeisintImp.submit(mq)
			break;
			
		case 13:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "v1_dossier_launch_forms")
			}
			V1SearchImp.submit(mq);
			break;
		case 14:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "search/searchform")
			}
			V1SearchImp.submit(mq);
			break;
			
		case 15:
			IaLndbImp.submit(mq);
			break;
		case 16:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "removecookie.do")
			}
			IaLndbImp.submit(mq);
			break;
		case 17:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "setcookie.do")
			}
			IaLndbImp.submit(mq);
			break;
		case 18:
			XLinkPubRecImp.submit(mq);
			// GetAndPrintImp.submit(mq)
			break;
		case 19:
			UrlApiPubRecImp.submit(mq);
			break;

		case 11:
		default:
			XLinkImp.submit(mq)
	}
};

/**
 * Takes a MasteryQuery object and its API matrix and converts it into
 * a query string.
 */
SearchImplementor.getQueryString = function(mq, matrix)
{
	var divider = "";
	var ret = "";

	for (var prop in mq)
	{
		if ((typeof mq[prop] != "object") && typeof mq[prop] != "function")
		{
			var key

			if (prop.substring(0, 2) == "c_")
			{
				key = prop.substring(2)
			}
			else
			{
				key = prop
			}
			if ((matrix[key] != -1) && (matrix[key] != -2))
			{
				if (!SearchImplementor.isNonAPIField(key) && Truth.isTrue(mq[prop]))
				{
					if (typeof matrix[key] == "string") {
						key = matrix[key];
					}
					
					try
					{
						// ret += divider + key + "=" + encodeURIComponent(mq[prop].toString())
						ret += divider + key + "=" + escape(mq[prop].toString())
					}
					catch(e)
					{
						ret += divider + key + "=" + escape(mq[prop].toString())
					}
					
					divider = "&";
				}
			}

		}
	}
	return ret;
};

/**
 * Takes a MasteryQuery object and its API matrix and converts it into
 * a query string.
 */
SearchImplementor.getQueryStringCaseInsensative = function(mq, matrix)
{
	var divider = "";
	var ret = "";

	for (var prop in mq)
	{
		if ((typeof mq[prop] != "object") && typeof mq[prop] != "function")
		{
			var key

			if (prop.substring(0, 2) == "c_")
			{
				key = prop.substring(2)
			}
			else
			{
				key = prop
			}


			if ((matrix[key.toLowerCase()] != -1) && (matrix[key.toLowerCase()] != -2))
			{
				if (!SearchImplementor.isNonAPIField(key.toLowerCase() && Truth.isTrue(mq[prop])))
				{
					if (typeof matrix[key.toLowerCase()] == "string") {
						key = matrix[key.toLowerCase()];
					}
					
					try
					{
						// ret += divider + key + "=" + encodeURIComponent(mq[prop].toString())
						ret += divider + key + "=" + escape(mq[prop].toString())
					}
					catch(e)
					{
						ret += divider + key + "=" + escape(mq[prop].toString())
					}
					
					divider = "&";
				}
			}
		}
	}

	return ret;
};

/**
 * Takes a MasteryQuery object and its API matrix and converts it into
 * the HTML for a hidden form post.
 */
SearchImplementor.getPostFields = function(mq, matrix)
{
	var ret = "";
	for (var prop in mq)
	{
		if ((typeof mq[prop] != "object") && typeof mq[prop] != "function")
		{
			var key

			if (prop.substring(0, 2) == "c_")
			{
				key = prop.substring(2)
			}
			else
			{
				key = prop
			}

			if ((matrix[key] != -1) && (matrix[key] != -2))
			{
				if (!SearchImplementor.isNonAPIField(key) && Truth.isTrue(mq[prop]))
				{
					if (typeof matrix[key] == "string") {
						key = matrix[key];
					}

					ret += FormUtil.getHiddenFieldVal(key, mq[prop].toString());
				}
			}
		}
	}
	

	return ret;
};

/**
 * Returns true for field names that are used for MasterQuery and not any specific
 * LN API
 */
SearchImplementor.isNonAPIField = function(field)
{
	switch(field) {
		case "api":
		case "method":
		case "target":
		case "override":
			return true;
		default:
			return false;
	}
};

/**
 * postit takes a MasterQuery Object, its API matrix and form action
 * and dynamically gererate a form out of it that will be posted to the
 * API.
 */
SearchImplementor.postit = function(mq, matrix, action)
{
	searchImplementorCount++

	mq = LNParser.convertDateToQuery(mq)

	var dForm    = document.createElement("form")
	dForm.name   = "mqdynaform" + searchImplementorCount
	dForm.id     = "mqdynaform" + searchImplementorCount
	dForm.action = action

	dForm.method = mq.method
	dForm.method = "GET"

	dForm.target = mq.target

	for (var prop in mq)
	{
		if (typeof mq[prop] != "object")
		{
			var key = prop;
			if (!SearchImplementor.isNonAPIField(key))
			{
				if (typeof matrix[prop] == "string") {
					key = matrix[prop];
				}
				var inp   = document.createElement("input");
				inp.type  = "hidden";
				inp.name  = key;
				inp.value = mq[prop].toString();
				dForm.appendChild(inp);
			}
		}
	}
	document.body.appendChild(dForm);

	dForm.submit();

};

SearchImplementor.submitDiv = function(formHTML)
{
	var diver = document.getElementById("masterQueryDynaFormDiv");

    //If the div already exists then delete it and append a new form
	if(diver != null)
	{
	    document.body.removeChild(document.getElementById("masterQueryDynaFormDiv"));
	}
    
	diver = document.createElement("div");
	diver.id = "masterQueryDynaFormDiv";
	
	diver.innerHTML = formHTML;
	
   	document.body.appendChild(diver);

	var dForm = document.getElementById("masterQueryDynaForm");

	dForm.submit();
}

SearchImplementor.tokenize = function(chunnel)
{
	var xmlObj = null;
	
	if(window.XMLHttpRequest)
    {
        xmlObj = new XMLHttpRequest();        
    }
    else if(window.ActiveXObject)
    {   
        try
        {
            xmlObj = new ActiveXObject("Msxml2.XMLHTTP");            
        }
        catch(e)
        {
            xmlObj = new ActiveXObject("Microsoft.XMLHTTP");            
        }
    }    
    else  
    {
        return false;
    }

	var file = "/clients/controls/Userinf/authTokenHelper.aspx";
	file = file + "?id=" + chunnel.getUID() + "&pwd=" + chunnel.getPWD();
	//alert(file);
	xmlObj.open ('GET', file, false);
	xmlObj.send (null);
      
	var temp;
	temp = xmlObj.responseText;
	
	chunnel.authToken = temp;
	chunnel.setUID("");
	chunnel.setPWD("");
	//alert(temp);

    return chunnel;
}/**
 * JavaScript Properties Class
 *
 * @class Class that takes a java-like properties file and turns it into
 * a JavaScript object.
 * <br /><br />
 * Only parses variables that are a key=value combination in which
 * the variable name is made up of alphanumeric characters. Otherwise
 * the line is ignored. 
 * <br /><br />
 * A sample property file:
 * <pre>     search=Paul Hackett
 *     after=8:DY
 *     source=NEWS;90days
 *     protocol=https:
 *     target=_blank
 *     override=chain2send.asp
 *     originationCode=00004
 *     api=8
 *     __TIME_DELAY__=2005:8:12:5:0:0;api;12</pre>
 *
 * USAGE:
 * <pre>var props = new JSProperties("properties.txt").getProperties();
 *alert(props.after);</pre>
 *
 * @version 0.1 
 * @requires HttpRequest HttpRequest Preferences Class
 * @author Christopher Baker <Christopher.Baker@lexisnexis.com>
 * @param {String} The filename for the properties file
 * @constructor
 */
function JSProperties() 
{
	this.filename = "js.properties.txt";
	
	if (arguments.length > 0)
	{
		this.filename = arguments[0];
	}
}

/**
 * Use XMLHttpRequest to read the properties file
 *
 * @return The properties as an Object
 * @type Object
 */
JSProperties.prototype.getProperties = function()
{
	var http = new HttpRequest();
	http.setTarget(this.filename);
	var pingGet = http.get();
	
	if (pingGet !== "") {
		return  JSProperties.parseProps(pingGet);
	}
	
	http.setTarget("../" + this.filename);
	pingGet = http.get();
	
	if (pingGet !== "") {
		return  JSProperties.parseProps(pingGet);
	}
	
   	throw new Error("Unable to find property file " + this.filename + ". Please verify that it is available.");
	
	return pingGet; 
};

/**
 * Method to parse an individual line.
 *
 * @private
 * @param {String} The raw properties file
 * @return The properties as an Object
 * @type Object
 */
JSProperties.parseProps = function(raw)
{

	var props = new Object();
	
	var lineArray = raw.split("\n");
	for (var i = 0; i < lineArray.length; i++)
	{
		
		var splitLine = lineArray[i].split("=");
		var key = trimAll(splitLine[0]);
		var val = trimAll(splitLine[1]);

		if (key)
		{
			// if the line begins with something other than a character or a number, do nothing.
			if (key.search(/^[_A-Za-z0-9]/) != -1)
			{
				props[key] = val;
			}
		}
	}
	return props;
};//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// DateUtil

/**
 * Utility methods related to dates.
 * @constructor
 * @private 
 */
function DateUtil(strRaw)
{
	throw new Error("DateUtil is a static class. Do not instantiate.");
}

/**
 * Converts common acceptable L/N Date formats into a standard mm/dd/yyyy format
 *
 *  Valid Formats
 *    * 01/01/1999
 *    * 01/01/99
 *    * 1/1/1999
 *    * 1/1/99
 *    * Jan. 1, 1999
 *    * jan. 1, 1999
 *    * Jan. 1, 99
 *    * Jan 1, 1999
 *    * jan 1, 1999
 *    * Jan 1, 99
 *    * January 1, 1999
 *    * january 1, 1999
 *    * January 1, 99
 */
DateUtil.parse = function(strRaw)
{
  var m = strRaw.match(/^([01]?\d|\w+)(\/|\.?\s+)([0123]?\d)(\/|,\s+)(\d{4}|\d{2})$/i);
  if (m !== null)
  {
    return DateUtil.parseMonth(m[1]) + "/" + DateUtil.parseNumericDay(m[3]) + "/" +  DateUtil.parseYear(m[5]); 
  }
  return;
};

/**
 * Converts numeric days into two digit absolute numbers.
 * For instance "1" returns "01"
 */
DateUtil.parseNumericDay = function(strRaw)
{
  if (strRaw.search(/^\d\d$/) != -1) return strRaw;
  return "0" + strRaw;
};

/**
 *
 */
DateUtil.parseYear = function(strRaw)
{
  // If it is a four digit year, just return ut
  if (strRaw.toString().search(/\d{4}/) != -1)
  {
    return strRaw;
  }
  var intValue = parseInt(strRaw, 10);
  if (intValue < 20)
  {
    return "20" + strRaw;
  }
  else
  {
    return "19" + strRaw;
  }
};

/**
 *
 */
DateUtil.parseMonth = function(strRaw)
{
  // Make sure that it is a string
  var str = strRaw.toString();
  str = str.toLowerCase();
  
  switch(str)
  {
    case("jan"):
    case("january"):
    case("1"):
    case("01"):
      return "01";
      break;
    case("feb"):
    case("february"):
    case("2"):
    case("02"):
      return "02";
      break;
    case("mar"):
    case("march"):
    case("3"):
    case("03"):
      return "03";
      break;
    case("apr"):
    case("april"):
    case("4"):
    case("04"):
      return "04";
      break;
    case("may"):
    case("5"):
    case("05"):
      return "05";
      break;
    case("jun"):
    case("june"):
    case("6"):
    case("06"):
      return "06";
      break;
    case("jul"):
    case("july"):
    case("7"):
    case("07"):
      return "07";
      break;
    case("aug"):
    case("august"):
    case("8"):
    case("08"):
      return "08";
      break;
    case("sep"):
    case("september"):
    case("9"):
    case("09"):
      return "09";
      break;
    case("oct"):
    case("october"):
    case("10"):
      return "10";
      break;
    case("nov"):
    case("november"):
    case("11"):
      return "11";
      break;
    case("dec"):
    case("december"):
    case("12"):
      return "12";
      break;
    default:
      return;      
  }
  return;
};

//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// FormUtil

/**
 * @constructor
 * @private
 */
function FormUtil()
{
	throw new Error("FormUtil is a static class. Do not instantiate.");
}

FormUtil.getHiddenFieldVal = function(fieldName, val)
{
	if (!Truth.isTrue(val)) 
	{
		return "";
	}
    while (val.indexOf("'") > -1)
    {
        val = val.replace("'", "&#39;");
    }
   	return "<input type='hidden' name='" + fieldName + "' value='" + val + "' />";
};

//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// QueryUtil

/**
 * @constructor
 * @private
 */
function QueryUtil()
{
	throw new Error("QueryUtil is a static class. Do not instantiate.");
}

QueryUtil.segment = function(strSeg) 
{
	return "(" + strSeg + ")"
};


//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// Truth

/**
 * @constructor
 * @private
 */
function Truth()
{
 
}

/** 
 * Static method to test truth from a Perl perspective
 */
Truth.isTrue = function(o) 
{
	if (o)
	{
		if (o === "") { return false; }
		return true;
	}
	return false;
};

/**
 * @private
 */
function escapeQuote(str)
{
	var re = new RegExp("'" , "g");
	return str.replace(re, "\'");

}


/**
 * Trim whitespace from the beginning and ending of a value.
 *
 * @param {String} The string to be trimmed
 * @return The string minus leading and trailing white space
 * @type String
 * @private
 */
function trimAll(sString)
{
	if (sString)
	{
		return sString.replace(/^\s*|\s*$/g,'');
	} 
	else
	{
		return sString;
	}
}function HttpRequest(returnType)
{
	// Are we returning XML or Text
	if (returnType) {
		this._returnType = returnType
	}
	else
	{
		this._returnType = HttpRequest.RESPONSE_TEXT
	}

	this.xmlhttp = new XMLHttpRequest();

	this.requestHeaders     = new Object();

	// Target defaults to self
	this._target = document.URL

	this._form

}

/**
 * Constant for returning XML
 */
HttpRequest.RESPONSE_XML = "responseXML"

/**
 * Constant for returning Text
 */
HttpRequest.RESPONSE_TEXT = "responseText"


HttpRequest.prototype.getTarget = function()
{
	return this._target
}

HttpRequest.prototype.setTarget = function(target)
{
	this._target = target
}

HttpRequest.prototype.getForm = function()
{
	return this._form
}

HttpRequest.prototype.setForm = function(form)
{
	if (typeof(form) == "object")
	{
		this._form = form.toString()
	}
	else
	{
		this._form = form
	}
}

HttpRequest.prototype._getURI = function()
{
	if (this._form) {
		return this._target + "?" + this._form
	}
	return this._target
}

HttpRequest.prototype.get = function(closure)
{
	if (closure)
	{
		this.asynchronousGet(closure)
	}
	return this.synchronousGet()
}

HttpRequest.prototype.post = function(closure)
{
	if (closure)
	{
		this.asynchronousPost(closure)
	}
	return this.synchronousPost()
}

HttpRequest.prototype.asynchronousGet = function(closure)
{
	// This, as in the this Object, no longer refers to this in closures,
	// so we need to copy it.
	// A good article on this is
	// http://w3future.com/html/stories/callbacks.xml
	var me = this

	// For asynchronous calls you can't use on
	var http = new XMLHttpRequest();
	http.open("GET", this._getURI(), true)

	http.onreadystatechange = function()
    {
        if(http.readyState == 4)
        {
            http.onreadystatechange = function(){}

            if (closure != null)
            {
				closure(http[me._returnType])
			}
        }
    };
	http.send(null)
}

HttpRequest.prototype.asynchronousPost = function(closure)
{
	var me = this
	var http = new XMLHttpRequest();

	http.open("POST", this.getTarget(), true);
	http.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8")

	http.onreadystatechange = function()
    {
        if(http.readyState == 4)
        {
            http.onreadystatechange = function(){}

            closure(http[me._returnType])
        }
    };
	http.send(this.getForm())
}


HttpRequest.prototype.synchronousGet = function()
{
	var ret = ""

	this.xmlhttp.open("GET", this._getURI(), false)

	for(header in this.requestHeaders)
	{
        this.xmlhttp.setRequestHeader(header, this.requestHeaders[header])
	}

	this.xmlhttp.send(null)
	if (this.xmlhttp.status == 200)
	{
		ret = this.xmlhttp.responseText
	}
	return ret
}

HttpRequest.prototype.synchronousPost = function(target, content)
{
	var ret = ""

	this.xmlhttp.open("POST", this.getTarget(), false);

	// Needed for form posting
	this.xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8")
	for(header in this.requestHeaders)
	{
        this.xmlhttp.setRequestHeader(header, this.requestHeaders[header])
	}

	this.xmlhttp.send(this.getForm())
	if (this.xmlhttp.status == 200)
	{
		ret = this.xmlhttp.responseText
	}
	return ret
}

////////////////////////////////////////////////////////////////////////////////
// XMLHttpRequest

/**
 * Cross-browser XMLHttpRequest instantiation. Posted by Gyoung-Yoon Noh
 * on the Ruby on Rails mailing list.
 *
 * Usage:
 *
 *        xmlhttp = new XMLHttpRequest()
 *
 * @author Gyoung-Yoon Noh
 * @link   http://hieraki.goodlad.ca/read/chapter/8#page16
 */


if ((typeof XMLHttpRequest == 'undefined') ||
	 (typeof XMLHttpRequest == null) ||
	  (typeof XMLHttpRequest == undefined))
{
	XMLHttpRequest = function ()
	{
		var msxmls = ['MSXML3', 'MSXML2', 'Microsoft']
		for (var i=0; i < msxmls.length; i++)
		{
			try
			{
				return new ActiveXObject(msxmls[i]+'.XMLHTTP')
			}
			catch (e) { }
		}
		//throw new Error("No XML component installed!")
	}
}








// XMLHttpRequest
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// URLBuilder

/**
 * Class to facilitate GET and POST query strings.
 *
 * Vars can be passed in through the constructor:
 *
 *    var u = new URLBuilder("word", "ping", "name", "pang")
 *
 * u.toString() returns "word=ping&name=pang"
 */
function URLBuilder()
{
	this._vars = new Object()

	if (arguments.length > 0)
	{
		for (var x = 0; x < arguments.length; x = x + 2)
		{
			if (arguments[x + 1] == undefined)
			{
				arguments[x + 1] = ""
			}
			this.addVar(arguments[x], arguments[x + 1])
		}
	}
}

URLBuilder.prototype.addVar = function(key, val)
{
	this._vars[encodeURIComponent(key)] = encodeURIComponent(val)
}

URLBuilder.prototype.toString = function()
{
	var delim = '';
	var url = '';
	for (key in this._vars)
	{
		url += delim + key + '=' + this._vars[key];
			delim = '&'
	}
	return url
}/**
 * @constructor
 * @private
 */
function CUIBuilderImp()
{
	throw new Error("CUIBuilderImp is a static class. Do not instantiate.");
}

CUIBuilderImp.DEFAULT_DOMAIN = "www.lexisnexis.com";

CUIBuilderImp.DEFAULT_VERB     = "CUI";

CUIBuilderImp.DEFAULT_LAYOUT   = "ss1";

// Create API Matrix
// The matrix is used to cast object elements into those used by the API.
CUIBuilderImp.matrix          = new Object();

// Filter out MQ fields that we don't want in the query string
// CUIBuilderImp.matrix.pwd      = -1;
// CUIBuilderImp.matrix.uid      = -1;
CUIBuilderImp.matrix.domain        = -1;
CUIBuilderImp.matrix.protocol      = -1;
CUIBuilderImp.matrix.lastName      = -1;
CUIBuilderImp.matrix.firstName     = -1;
CUIBuilderImp.matrix.companyName   = -1;
CUIBuilderImp.matrix.ssn           = -1;
CUIBuilderImp.matrix.streetAddress = -1;	
CUIBuilderImp.matrix.city          = -1;	
CUIBuilderImp.matrix.state         = -1;	
CUIBuilderImp.matrix.zip           = -1;	
CUIBuilderImp.matrix.apinoadf      = -1;	
CUIBuilderImp.matrix.verb          = -1;	
CUIBuilderImp.matrix.TOCTarget     = -1;	
	
// Describe which field names you need to cast into other values
// specific to the API.
CUIBuilderImp.matrix.client          = "clientID";
CUIBuilderImp.matrix.originationCode = "OriginCode";	
CUIBuilderImp.matrix.search          = "query";
CUIBuilderImp.matrix.source          = "src";
CUIBuilderImp.matrix.uid             = "UID";
CUIBuilderImp.matrix.pwd             = "PWD";	
	
/**
 * This matric 
 */
CUIBuilderImp.submit = function(chunnel)
{
	// Preprocessor needs to convert generic after field 
	// to XLink's relativedate field
	chunnel = CUIBuilderImp._preprocessor(chunnel);

	var linker = CUIBuilderImp.getLink(chunnel);

	// If no target, set the target for the same window.	
	if (!Truth.isTrue(chunnel.target))
	{
		chunnel.target = "_self";
	}
	
	// prompt("", linker)
	// And send it on its merry way
	var w = window.open(linker, chunnel.target, NEW_WINDOW_FEATURES); 

};

/**
 * Take any actions that need to be made on the MQ object before it gets
 * submitted to its specific API.
 */
CUIBuilderImp._preprocessor =  function(chunnel)
{
	if (Truth.isTrue(chunnel.pwd))
	{
		chunnel.protocol = "https:";
	}
	
	if (!Truth.isTrue(chunnel.get("layout")))
	{
		chunnel.set("layout", CUIBuilderImp.DEFAULT_LAYOUT)
	}
	
	if (!Truth.isTrue(chunnel.get("verb")))
	{
		chunnel.set("verb", CUIBuilderImp.DEFAULT_VERB)
	}
	
	// If CUI Token isn't set, set it. 
	if (!Truth.isTrue(chunnel.get("cuiToken")))
	{
		var http = new HttpRequest();
		http.setTarget(MasterQuery.baseURL + "getCUIToken.asp");
		chunnel.set("cuiToken", http.get());
	}
	
	return chunnel;
}

CUIBuilderImp.getLink = function(chunnel)
{
	var domain = CUIBuilderImp.DEFAULT_DOMAIN;
	
	if (Truth.isTrue(chunnel.domain)) 
	{
		domain = chunnel.domain;
	}
	
	var action;
	
	if (Truth.isTrue(chunnel.override))
	{
		action = chunnel.override;
	}
	else
	{
		action = chunnel.protocol + "//" + domain + "/clients/";
		
		switch(chunnel.get("verb").toUpperCase())
		{
			case "CUIINT":
				action += "CUIInt/search.asp";
				break;
			case "PQS":
				action += "CUIInt/pqs.asp";
				break;
			case "CUI":
			default:
				action += "CUI/search.asp";
				break;
		}	
		
	}

	return action + "?" + SearchImplementor.getQueryString(chunnel, CUIBuilderImp.matrix);

};/**
 * @constructor
 * @private
 */
function DossierImp()
{
	throw new Error("DossierImp is a static class. Do not instantiate.");
}

DossierImp.DEFAULT_DOMAIN = "web.lexis-nexis.com";

// Create API Matrix
// The matrix is used to cast object elements into those used by the API.
DossierImp.matrix          = new Object();

// Filter out MQ fields that we don't want in the query string
// DossierImp.matrix.pwd      = -1;
// DossierImp.matrix.uid      = -1;
DossierImp.matrix.domain        = -1;
DossierImp.matrix.protocol      = -1;
DossierImp.matrix.lastName      = -1;
DossierImp.matrix.firstName     = -1;
// DossierImp.matrix.companyName   = -1;
DossierImp.matrix.ssn           = -1;
DossierImp.matrix.streetAddress = -1;	
// DossierImp.matrix.city          = -1;	
DossierImp.matrix.apinoadf      = -1;	
DossierImp.matrix.TOCTarget     = -1;	

	
// Describe which field names you need to cast into other values
// specific to the API.
DossierImp.matrix.client          = "clientid";
DossierImp.matrix.menu            = -1;
DossierImp.matrix.originationCode = "ORIGINATION_CODE";	
DossierImp.matrix.search          = "name";
DossierImp.matrix.source          = -1;
DossierImp.matrix.uid             = "USER_ID";
DossierImp.matrix.pwd             = "PASSWORD";	

DossierImp.matrix.state           = "StateList";
DossierImp.matrix.zip		      = "zipcode";


/**
 * This matric 
 */
DossierImp.submit = function(chunnel)
{
	// Preprocessor needs to convert generic after field 
	// to XLink's relativedate field
	chunnel = DossierImp._preprocessor(chunnel);

	var linker = DossierImp.getLink(chunnel);

	// If no target, set the target for the same window.	
	if (!Truth.isTrue(chunnel.target))
	{
		chunnel.target = "_self";
	}
	
	// prompt("", linker)
	// And send it on its merry way
	var w = window.open(linker, chunnel.target, NEW_WINDOW_FEATURES); 

};

/**
 * Take any actions that need to be made on the MQ object before it gets
 * submitted to its specific API.
 */
DossierImp._preprocessor =  function(chunnel)
{
	if (Truth.isTrue(chunnel.pwd))
	{
		chunnel.protocol = "https:";
		if (!Truth.isTrue(chunnel.get("LNAUTHSCHEME")))
		{
			chunnel.set("LNAUTHSCHEME", "C");
		}
	}
	
	if (!Truth.isTrue(chunnel.get("prod")))
	{
		chunnel.set("prod", "CD")
	}
	
	return chunnel;
}

DossierImp.getLink = function(chunnel)
{
	var domain = DossierImp.DEFAULT_DOMAIN;
	
	if (chunnel.domain && chunnel.domain !== "") 
	{
		domain = chunnel.domain;
	}
	
	var action;
	
	if (Truth.isTrue(chunnel.override))
	{
		action = chunnel.override;
	}
	else
	{
		action = chunnel.protocol + "//" + domain + "/api.universe/v1_dossier_launch_results";
	}

	return action + "?" + SearchImplementor.getQueryString(chunnel, DossierImp.matrix);

};/**
 *
 *
 * The LexisNexis Professional API implementor employs a verb interface the same
 * as the Rosetta URL API. Setting the verb paramater dictates which Professional
 * API that MQ hits. There are the following verbs available:
 *
 *		- apisearch
 *      - apibrowse
 *      - hushlogin
 *      - logout
 *      - source
 *      - sourcelist
 * @constructor
 * @private
 */
function LNProfImp()
{
	throw new Error("LNProfImp is a static class. Do not instantiate.");
}

LNProfImp.DEFAULT_DOMAIN = "web.lexis-nexis.com/professional/";

LNProfImp.DEFAULT_VERB     = "apisearch";

// Create API Matrix
// The matrix is used to cast object elements into those used by the API.
LNProfImp.matrix          = new Object();

// Filter out MQ fields that we don't want in the query string
LNProfImp.matrix.pwd           = -1;
LNProfImp.matrix.uid           = -1;
LNProfImp.matrix.domain        = -1;
LNProfImp.matrix.protocol      = -1;
LNProfImp.matrix.lastName      = -1;
LNProfImp.matrix.firstName     = -1;
LNProfImp.matrix.companyName   = -1;
LNProfImp.matrix.ssn           = -1;
LNProfImp.matrix.streetAddress = -1;
LNProfImp.matrix.city          = -1;
LNProfImp.matrix.state         = -1;
LNProfImp.matrix.zip           = -1;
LNProfImp.matrix.apinoadf      = -1;

LNProfImp.matrix.verb          = -1;
LNProfImp.matrix.TOCTarget     = -1;	


// Describe which field names you need to cast into other values
// specific to the API.
LNProfImp.matrix.client          = "clientid";
LNProfImp.matrix.originationCode = "ORIGINATION_CODE";
LNProfImp.matrix.search          = "searchTerm";
LNProfImp.matrix.sort            = "sortby";

LNProfImp.matrix.fromDate        = "dateFrom";
LNProfImp.matrix.toDate          = "dateTo";
LNProfImp.matrix.after           = "dateRelative";


/**
 * This matric
 */
LNProfImp.submit = function(chunnel)
{
	LNProfImp._preprocessor(chunnel);
	
	var linker = LNProfImp.getLink(chunnel);

	// prompt("", linker)

	// If no target, set the target for the same window.
	if (!Truth.isTrue(chunnel.getTarget()))
	{
		chunnel.target = "_self";
	}
	
	var w;

	if (Truth.isTrue(chunnel.getPWD()))
	{
		var aT = "https://" + LNProfImp.DEFAULT_DOMAIN + "hushlogin";
 		aT = aT + "?USER_ID=" + chunnel.getUID();
 		aT = aT + "&PASSWORD=" + chunnel.getPWD();
 		if (Truth.isTrue(chunnel.get("keep")))
 		{
 			aT = aT + "&keep=" + chunnel.get("keep");
 		}
 		if (Truth.isTrue(chunnel.get("language")))
 		{
 			aT = aT + "&language=" + chunnel.get("language");
 		}
 		
 		if (chunnel.get("verb") == "hushlogin")
 		{
 			if (Truth.isTrue(chunnel.get("redirect")))
 			{
 				aT = aT + "&redirect=" + escape(chunnel.get("redirect"));
 			}
 		}
 		else
 		{
			aT = aT + "&redirect=" + escape(linker);
			
		}
		// prompt("", aT);
		w = window.open(aT, chunnel.target, NEW_WINDOW_FEATURES);
	}
	else
	{
		// prompt("", linker);
		// And send it on its merry way
		w = window.open(linker, chunnel.target, NEW_WINDOW_FEATURES);
	}
};

/**
 * Take any actions that need to be made on the MQ object before it gets
 * submitted to its specific API.
 */
LNProfImp._preprocessor =  function(chunnel)
{
	if (!Truth.isTrue(chunnel.get("verb")))
	{
		chunnel.set("verb", "apisearch")
	}
	return chunnel;
};

LNProfImp.getLink = function(chunnel)
{
	var domain = LNProfImp.DEFAULT_DOMAIN;

	if (Truth.isTrue(chunnel.getDomain()))
	{
		domain = chunnel.domain;
	}

	var action;

	if (Truth.isTrue(chunnel.override))
	{
		action = chunnel.override;
	}
	else
	{
		var verb = LNProfImp.DEFAULT_VERB;
		if (Truth.isTrue(chunnel.get("verb")))
		{
			verb = chunnel.get("verb");
		}

		action = chunnel.protocol + "//" + domain + verb;

	}
	
	var r = action + "?" + SearchImplementor.getQueryString(chunnel, LNProfImp.matrix);

	return r;

};/**
 * @constructor
 * @private
 */
function SeisintImp()
{
	throw new Error("SeisintImp is a static class. Do not instantiate.");
}

// CONSTANTS
SeisintImp.DEFAULT_DOMAIN          = "www.lexis.com";
// SeisintImp.DEFAULT_DOMAIN          = "cert-2610.lexis.com";
// SeisintImp.DEFAULT_DOMAIN          = "wmitzjx.lexis.com";


SeisintImp.SMRTLX_COMPANY_LIBFILE  = "SMRTLX;BSNRPT"
SeisintImp.SMRTLX_PERSONAL_LIBFILE = "SMRTLX;PERRPT"
SeisintImp.SMRTLX_LOCATION_LIBFILE = "SMRTLX;LOCRPT"

SeisintImp.SMRTLX_COMPANY_CSI      = "174612"
SeisintImp.SMRTLX_PERSONAL_CSI     = "174611"
SeisintImp.SMRTLX_LOCATION_CSI     = "174613"

SeisintImp.SEISNT_COMPANY_LIBFILE  = "SMRTLX;BSNRPT"
SeisintImp.SEISNT_PERSONAL_LIBFILE = "SMRTLX;PERRPT"
SeisintImp.SEISNT_LOCATION_LIBFILE = "SMRTLX;LOCRPT"


// Create API Matrix
// The matrix is used to cast object elements into those used by the API.
SeisintImp.matrix          = new Object();

// Filter out MQ fields that we don't want in the query string
SeisintImp.matrix.pwd           = -1;
SeisintImp.matrix.uid           = -1;
SeisintImp.matrix.domain        = -1;
SeisintImp.matrix.protocol      = -1;

SeisintImp.matrix.lastName      = -1;
SeisintImp.matrix.firstName     = -1;
SeisintImp.matrix.companyName   = -1;
SeisintImp.matrix.ssn           = -1;
SeisintImp.matrix.streetAddress = -1;
SeisintImp.matrix.state         = -1;
SeisintImp.matrix.zip           = -1;
SeisintImp.matrix.telephone     = -1;
SeisintImp.matrix.birthDate     = -1;
SeisintImp.matrix.searchRadius  = -1;
SeisintImp.matrix.TOCTarget     = -1;	

// Describe which field names you need to cast into other values
// specific to the API.
SeisintImp.matrix.originationCode = "ORIGINATION_CODE";
	
/**
 * This matric 
 */
SeisintImp.submit = function(chunnel)
{
	// Preprocessor needs to convert generic after field 
	// to XLink's relativedate field
	SeisintImp._preprocessor(chunnel);

	// If no target, set the target for the same window.	
	if (!Truth.isTrue(chunnel.target))
	{
		chunnel.target = "_self";
	}
	
	// Get the XML
	var xml;
SeisintImp.SMRTLX_COMPANY_CSI      = "174612"


	switch(chunnel.getSource())
	{
		case SeisintImp.SMRTLX_COMPANY_LIBFILE:
		case SeisintImp.SMRTLX_COMPANY_CSI:
			xml = SeisintImp.getBusinessXML(chunnel);
			chunnel.set("reporttype", "BUS");
			break;
		case SeisintImp.SMRTLX_LOCATION_LIBFILE:
		case SeisintImp.SMRTLX_LOCATION_CSI:
			xml = SeisintImp.getLocationXML(chunnel);
			chunnel.set("reporttype", "LOC");
			break;
		case SeisintImp.SMRTLX_PERSONAL_LIBFILE:
		case SeisintImp.SMRTLX_PERSONAL_CSI:
		default:
			xml = SeisintImp.getPersonXML(chunnel);
			chunnel.set("reporttype", "PER");
			break;
	}
	
	chunnel.setSearchtype("seisint");
	chunnel.setSearch("");
	chunnel.setMenu("");
	// chunnel.setSource("");
	
	// chunnel.set("mj", "");
	// chunnel.setMenu("MIDDLEWARE_CODE", "");
	
	var linker = SeisintImp.getLink(chunnel);
	

	var f = "<form method='post' action='";
	f += linker;
	f += "' id='masterQueryDynaForm' name='masterQueryDynaForm' target='"
	f += chunnel.target
	f += "'>";
	
	f += FormUtil.getHiddenFieldVal('USER_ID', chunnel.getUID());
	f += FormUtil.getHiddenFieldVal('PASSWORD', chunnel.getPWD());
	f += FormUtil.getHiddenFieldVal('LNAUTHSCHEME', 'CP');
	f += FormUtil.getHiddenFieldVal('xsearch', xml);

	f += "</form>";

	var diver = document.getElementById("masterQueryDynaFormDiv");
	
	// Only create a new div if the existing div doesn't exist
	if (diver == null)
	{
		diver = document.createElement("div");
		diver.id = "masterQueryDynaFormDiv"
	}
	
	diver.innerHTML = f;
	document.body.appendChild(diver);
	
	var dForm = document.getElementById("masterQueryDynaForm");

	// prompt("", linker)

	dForm.submit();

	
	chunnel = null;
};

/**
 * Take any actions that need to be made on the MQ object before it gets
 * submitted to its specific API.
 */
SeisintImp._preprocessor =  function(chunnel)
{
	var relativedate = LNParser.convertAfterToRelative(chunnel.getAfter());
	chunnel.c_relativedate = relativedate;
	chunnel.after = "";
	
	if (Truth.isTrue(chunnel.pwd))
	{
		chunnel.protocol = "https:";
	}
	return chunnel;
}

SeisintImp.getLink = function(chunnel)
{
	var domain = SeisintImp.DEFAULT_DOMAIN;
	
	if (chunnel.domain && chunnel.domain !== "") 
	{
		domain = chunnel.domain;
	}
	
	var action
	
	if (Truth.isTrue(chunnel.override))
	{
		action = chunnel.override
	}
	else
	{
		action = chunnel.protocol + "//" + domain + "/research/xlink";
	}

	return action + "?" + SearchImplementor.getQueryString(chunnel, SeisintImp.matrix);

};


SeisintImp.getPersonXML = function(chunnel)
{
	var xml = '<search type="person"><fieldList>';
	
	if (Truth.isTrue(chunnel.get("firstName"))) 
	{
		xml += SeisintImp.getField(chunnel.get("firstName"), "firstName", "First Name");
	}
	if (Truth.isTrue(chunnel.get("lastName"))) 
	{
		xml += SeisintImp.getField(chunnel.get("lastName"), "lastName", "Last Name");
	}
	if (Truth.isTrue(chunnel.get("middleName"))) 
	{
		xml += SeisintImp.getField(chunnel.get("middleName"), "middleName", "Middle Name");
	}
	if (Truth.isTrue(chunnel.get("similiarLastName"))) 
	{
		xml += SeisintImp.getField(chunnel.get("similiarLastName"), "similiarLastName", "Sounds Like");
	}
	if (Truth.isTrue(chunnel.get("streetAddress"))) 
	{
		xml += SeisintImp.getField(chunnel.get("streetAddress"), "streetAddress", "Street");
	}
	if (Truth.isTrue(chunnel.get("city"))) 
	{
		xml += SeisintImp.getField(chunnel.get("city"), "city", "City");
	}
	if (Truth.isTrue(chunnel.get("state"))) 
	{
		xml += SeisintImp.getField(chunnel.get("state"), "state", "State");
	}
	if (Truth.isTrue(chunnel.get("zip"))) 
	{
		xml += SeisintImp.getField(chunnel.get("zip"), "zip", "ZIP");
	}
	if (Truth.isTrue(chunnel.get("searchRadius"))) 
	{
		xml += SeisintImp.getField(chunnel.get("searchRadius"), "searchRadius", "Search Radius");
	}
	if (Truth.isTrue(chunnel.get("telephone"))) 
	{
		xml += SeisintImp.getField(chunnel.get("telephone"), "telephone", "Telephone");
	}
	if (Truth.isTrue(chunnel.get("ssn"))) 
	{
		xml += SeisintImp.getField(chunnel.get("ssn"), "ssn", "SSN");
	}
	if (Truth.isTrue(chunnel.get("birthDate"))) 
	{
		xml += SeisintImp.getField(chunnel.get("birthDate"), "birthDate", "Birth Date");
	}

	return xml + '</fieldList></search>';

};


SeisintImp.getBusinessXML = function(chunnel)
{
	var xml = '<search type="business"><fieldList>';

	if (Truth.isTrue(chunnel.get("companyName"))) 
	{
		xml += SeisintImp.getField(chunnel.get("companyName"), "companyName", "Company Name");
	}	
	if (Truth.isTrue(chunnel.get("streetAddress"))) 
	{
		xml += SeisintImp.getField(chunnel.get("streetAddress"), "streetAddress", "Street");
	}
	if (Truth.isTrue(chunnel.get("city"))) 
	{
		xml += SeisintImp.getField(chunnel.get("city"), "city", "City");
	}
	if (Truth.isTrue(chunnel.get("state"))) 
	{
		xml += SeisintImp.getField(chunnel.get("state"), "state", "State");
	}
	if (Truth.isTrue(chunnel.get("zip"))) 
	{
		xml += SeisintImp.getField(chunnel.get("zip"), "zip", "ZIP");
	}
	if (Truth.isTrue(chunnel.get("telephone"))) 
	{
		xml += SeisintImp.getField(chunnel.get("telephone"), "telephone", "Telephone");
	}

	if (Truth.isTrue(chunnel.get("firstName"))) 
	{
		xml += SeisintImp.getField(chunnel.get("firstName"), "firstName", "First Name");
	}
	if (Truth.isTrue(chunnel.get("lastName"))) 
	{
		xml += SeisintImp.getField(chunnel.get("lastName"), "lastName", "Last Name");
	}
	return xml + '</fieldList></search>';

};


SeisintImp.getLocationXML = function(chunnel)
{
	var xml = '<search type="location"><fieldList>';

	if (Truth.isTrue(chunnel.get("streetAddress"))) 
	{
		xml += SeisintImp.getField(chunnel.get("streetAddress"), "streetAddress", "Street");
	}
	if (Truth.isTrue(chunnel.get("city"))) 
	{
		xml += SeisintImp.getField(chunnel.get("city"), "city", "City");
	}
	if (Truth.isTrue(chunnel.get("state"))) 
	{
		xml += SeisintImp.getField(chunnel.get("state"), "state", "State");
	}
	if (Truth.isTrue(chunnel.get("zip"))) 
	{
		xml += SeisintImp.getField(chunnel.get("zip"), "zip", "ZIP");
	}

	return xml + '</fieldList></search>';

};


SeisintImp.getField = function(value, type, formId)
{
	if (formId === null) 
	{
		formId = type;
	}

	value = value.replace(/\W/g, " ");
	
	return '<field type="' + type + '" formId="' + formId + '">' + value + '</field>';

};

SeisintImp.useGet = function(chunnel)
{
	if (Truth.isTrue(chunnel.pwd) && Truth.isTrue(chunnel.uid)) 
	{
		return false;
	}
	if (Truth.isTrue(chunnel.getSearch()))
	{
		return false;
	}
	return true;
}




/**
 * Please use ppcmixed2/ppccpwd77 as id/pwd for uk/legal.
 *
 * http://www.lexisnexis.com/uk/legal/api/version1/sr?csi=267991&sr=police and legal&hd=t
 * @constructor
 * @private -
 */
function UrlApiImp()
{
	throw new Error("V1SearchImp is a static class. Do not instantiate.");
}

UrlApiImp.DEBUG            = true;

UrlApiImp.DEFAULT_DOMAIN       = "www.lexisnexis.com";
UrlApiImp.DEFAULT_NEXIS_DOMAIN = "w3.nexis.com";
// UrlApiImp.DEFAULT_DOMAIN      = "w5cdc12.lexisnexis.com";
UrlApiImp.DEFAULT_ADAPTION     = "uk";
UrlApiImp.DEFAULT_TYPE         = "legal";
UrlApiImp.DEFAULT_API_VERSION  = "api/version1";
UrlApiImp.DEFAULT_VERB         = "sr";

// Create API Matrix
// The matrix is used to cast object elements into those used by the API.
UrlApiImp.matrix          = new Object();

// Filter out MQ fields that we don't want in the query string

UrlApiImp.matrix.adaption   = -1;
UrlApiImp.matrix.domain     = -1;
UrlApiImp.matrix.protocol   = -1;
UrlApiImp.matrix.type       = -1;
UrlApiImp.matrix.apiVersion = -1;
UrlApiImp.matrix.verb       = -1;
//UrlApiImp.matrix.searchtype = -1;
UrlApiImp.matrix.TOCTarget     = -1;	

UrlApiImp.matrix.host       = -1;

UrlApiImp.matrix.pwd    = "pw";
UrlApiImp.matrix.uid    = "ui";

// These fields don't exist in Rosetta
UrlApiImp.matrix.maxdocs  = -1;
UrlApiImp.matrix.zone     = -1;
UrlApiImp.matrix.citation = -1;
UrlApiImp.matrix.prod     = -1;


// Describe which field names you need to cast into other values
// specific to the API.

UrlApiImp.matrix.originationCode = "oc";
UrlApiImp.matrix.client = "pi";
UrlApiImp.matrix.search = "sr";
UrlApiImp.matrix.searchtype = "stp";

UrlApiImp.matrix.source = "csi";
UrlApiImp.matrix.sort   = "so";

// DOSSIER FIELDS
UrlApiImp.matrix.ticker = "tr";
UrlApiImp.matrix.name   = "nm";

// api.universe/search/searchform
UrlApiImp.matrix.id     = -1;


/**
 * Takes a chunnel object and submits it. The last step in the journey
 * of a chunnel object before it becomes a LN search result.
 */
UrlApiImp.submit = function(chunnel)
{
	try
	{
		// Preprocessor needs to convert generic after field 
		// to XLink's relativedate field
		UrlApiImp.preprocessor(chunnel);

		// If no target, set the target for the same window.	
		if (!Truth.isTrue(chunnel.target))
		{
			chunnel.target = "_self";
		}
		
		if (chunnel.get("verb") == "au")
		{
			UrlApiImp._submitAu(chunnel);
			return;
		}
		
		var linker = UrlApiImp.getLink(chunnel);
        if (((!Truth.isTrue(chunnel.pwd) && chunnel.get("verb") != "activate") || Truth.isTrue(chunnel.override))  && chunnel.method != "POST")
		{
			var w = window.open(linker, chunnel.target, NEW_WINDOW_FEATURES); 
		}
		else
		{
            var f = UrlApiImp.getPostForm(chunnel);
			
	        if (chunnel.get("robtest")) {if (!confirm("1: " + f)) return false};
			SearchImplementor.submitDiv(f);
		}
		
		chunnel = null;
	}
	catch(ex)
	{
		if (UrlApiImp.DEBUG)
		{
			alert(ex.message)
		}
	}
};

UrlApiImp.libfileToCSI = function(libfile)
{
	if (libfile.lastIndexOf(";") != -1) {
		var http = new HttpRequest();
		http.setTarget(MasterQuery.baseURL + "getCSI.asp");
		http.setForm(new URLBuilder("libfile", libfile))
		var csi = http.get();
		if (csi)
		{
			return csi;
		}		
	} 
	return libfile;
}

/**
 * Submit using the authentication verb
 */
UrlApiImp._submitAu =  function(chunnel)
{

    chunnel.setProtocol("https:")

    var f = UrlApiImp.getPostForm(chunnel);

	if (chunnel.get("robtest")) {if (!confirm("2: " + f)) return false};

	SearchImplementor.submitDiv(f);
}

UrlApiImp._submitSo =  function(chunnel)
{
	window.open(UrlApiImp.getVerbPath(chunnel), chunnel.target, NEW_WINDOW_FEATURES); 
}

/**
 * Take any actions that need to be made on the MQ object before it gets
 * submitted to its specific API.
 */
UrlApiImp.preprocessor =  function(chunnel)
{
	if (!Truth.isTrue(chunnel.get("adaption")))
	{
		chunnel.set("adaption", UrlApiImp.DEFAULT_ADAPTION);
	}
	
	format = "us";
	
	if (chunnel.get("adaption") != "nexis")
	{
		format = "uk";
	}

	chunnel = LNParser.convertDateToQuery(chunnel, format);
	
	if (Truth.isTrue(chunnel.getSort()))
	{
		chunnel.setSort("da");
	}
	
	if (Truth.isTrue(chunnel.pwd))
	{
		// not working for auth
		// chunnel.protocol = "https:";
	}
	
	if (!Truth.isTrue(chunnel.get("type")))
	{
		chunnel.set("type", UrlApiImp.DEFAULT_TYPE);
	}
	
	//Make alerts work
	if (!Truth.isTrue(chunnel.get("icvrpg")))
	{
		chunnel.set("icvrpg", true);
	}
	
	if (!Truth.isTrue(chunnel.get("verb")))
	{
		chunnel.set("verb", UrlApiImp.DEFAULT_VERB);
	}
	
	
	// For UK Rebranding.  Changes uk/business mq calls to use uk/nexis
	if ((chunnel.get("adaption") == "uk") && (chunnel.get("type") == "business"))
	{
	    chunnel.set("type", "nexis");
	}
	
	if (chunnel.get("rt"))
	    chunnel.set("rt", chunnel.get("rt").toLowerCase().replace(new RegExp("uk/business", "g"), "uk/nexis").replace("sourceinfo.do", "sourceInfo.do"));
    
    
	//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
	// Auto-convert libfile to CSI numbers
	
	//chunnel.setSource(UrlApiImp.libfileToCSI(chunnel.getSource()));
	
	//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
	// LEXSEE & LEXSTAT
	
	var type = chunnel.getSearchtype();
	
	switch(type)
	{
		case "get":
		case "lexsee":
		case "lxe":
		case "lexstat":
		
			// Make sure that the source isn't already set
			if (!Truth.isTrue(chunnel.getSource())) 
			{
				// http://psc744:6060/ssdf/guide/dynmff/bin/dynmff.pl?type=library&csi=12660&lvl=3
				// Source: MEGA
				// chunnel.setSource("12660")
				chunnel.setSource("138150")
				// 
			}
			break;
	
		default:
			break;
	}
	
	//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
	// CUI BUILDER CITATION
	
	// &citation=1+us+1
	if (Truth.isTrue(chunnel.get("citation")))
	{
		if (!Truth.isTrue(chunnel.getSource()) && !Truth.isTrue(chunnel.getSearch()))
		{
			chunnel.setSearch(chunnel.get("citation"))
			chunnel.setSource("12660")
		} 
	}
	
	//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
	// Nexis searchforms
	
	if (chunnel.get("id")) 
	{

		chunnel.set("verb", "sf")
		
		switch(chunnel.get("id"))
		{
			// Power Search
			case "-99":
				chunnel.set("sfi", "US00NBGenSrch");
				break;
			// US Reports // Company Profile Page
			case "1928":
				chunnel.set("sfi", "US02NBCmpSrch");
				break;
			// SEC Filings
			case "1940":
			case "2378":
				chunnel.set("sfi", "US02NBSECFilSrch");
				break;
			// Mergers & Acquisitions 
			case "1945":
				chunnel.set("sfi", "US02NBMergAcqSrch");
				break;
			// Business Locator/Assets
			case "1930":
				chunnel.set("sfi", "US04NBBusLocSrch");
				break;
			// Asset Locator
			case "2515":
				chunnel.set("sfi", "US04NBAssetLocSrch");
				break;
			// Bankruptcy Filings
			case "1375":
			case "2517":
				chunnel.set("sfi", "US04NBBankrupSrch");
				break;	
			// Judgments
			case "2519":
				chunnel.set("sfi", "US04NBJudLiensSrch");
				break;
			// Licenses
			case "2522":
				chunnel.set("sfi", "US04NBLicensesSrch");
				break;
			// Civil &amp; Criminal Filings
			case "2523":
				chunnel.set("sfi", "US04NBCivCrimSrch");
				break;	
			// D&B
			case "2524":
				chunnel.set("sfi", "US02NBDunBradSrch");
				break;
			// Motor Vehicles Registrations 
			case "2727":
				chunnel.set("sfi", "US04NBDriverSrch");
				break;
			// Motor Vehicle Registrations
			case "2729":
				chunnel.set("sfi", "US04NBMotVehSrch");
				break;
			// General News 
			case "2888":
				chunnel.set("sfi", "US01NBSimplSrch");
				break;
			// Edgar - SEC Real Time Filings
			case "2911":
				chunnel.set("sfi", "US02NBEdgarSrch");
				break;
		}
	}

	return chunnel;
};




/**
 * Returns the link that is the target for the API call.
 * This can be used as the action for a form or as the location
 * for a called to window.open.
 *
 * The query string is return based upon the chunnel values filtered 
 * through the implementor's matrix
 */
UrlApiImp.getLink = function(chunnel)
{
	var qs = SearchImplementor.getQueryString(chunnel, UrlApiImp.matrix);
	
	if (Truth.isTrue(qs))
	{
		return UrlApiImp.getVerbPath(chunnel) + "?" + qs;
	}
	else
	{
		return UrlApiImp.getVerbPath(chunnel);
	}
};

/**
 * Returns the form HTML to be used for a Post call.
 **/
UrlApiImp.getPostForm = function(chunnel)
{
    var f = "<form method='post' action='";
    f += UrlApiImp.getVerbPath(chunnel);
	f += "' id='masterQueryDynaForm' name='masterQueryDynaForm' target='";
	f += chunnel.target;
	f += "'>";
    f += SearchImplementor.getPostFields(chunnel, UrlApiImp.matrix)
	f += "</form>";
	return f;
};

/**
 * Returns the link that is the target for the API call.
 * This can be used as the action for a form or as the location
 * for a called to window.open.
 *
 * The query string is return based upon the chunnel values filtered 
 * through the implementor's matrix
 */
UrlApiImp.getVerbPath = function(chunnel)
{
	var domain = UrlApiImp.DEFAULT_DOMAIN;

	if (chunnel.domain !== "" && chunnel.get("adaption") == "nexis")
	{
		domain = UrlApiImp.DEFAULT_NEXIS_DOMAIN;
	}
	
	if (chunnel.domain && chunnel.domain !== "") 
	{
		domain = chunnel.domain;
	}
	
	if (Truth.isTrue(chunnel.override))
	{
		return chunnel.override;
	}
	else
	{
		var adaption = chunnel.get("adaption")
		
		if (adaption == "nexis")
		{
			adaption = "new"
		}
	
		var adLink = chunnel.protocol + "//" + domain + "/" + adaption;
	
		if (chunnel.get("adaption") != "nexis")
		{
			adLink += "/" + chunnel.get("type")
		}
		
		if (chunnel.get("verb") == "home")
		{
			return adLink + "/home/home.do";
		}
		else
		{
			var apiVersion = UrlApiImp.DEFAULT_API_VERSION;
			
			if (chunnel.get("verb") == "accessGW") {
				var apiVersion = "api";
			}
			
			if (Truth.isTrue(chunnel.get("apiVersion")))
			{
				apiVersion = chunnel.get("apiVersion");
			}

			return adLink + "/" + apiVersion + "/" + chunnel.get("verb");	
		}
	}
};
/**
 * @constructor
 * @private
 */
function V1SearchImp()
{
	throw new Error("V1SearchImp is a static class. Do not instantiate.");
}

V1SearchImp.DEFAULT_DOMAIN = "web.lexis-nexis.com";
V1SearchImp.DEFAULT_VERB   = "v1_search";

// Create API Matrix
// The matrix is used to cast object elements into those used by the API.
V1SearchImp.matrix          = new Object();

// Filter out MQ fields that we don't want in the query string
// V1SearchImp.matrix.pwd      = -1;
// V1SearchImp.matrix.uid      = -1;
V1SearchImp.matrix.domain        = -1;
V1SearchImp.matrix.protocol      = -1;
V1SearchImp.matrix.lastName      = -1;
V1SearchImp.matrix.firstName     = -1;
V1SearchImp.matrix.companyName   = -1;
V1SearchImp.matrix.ssn           = -1;
V1SearchImp.matrix.streetAddress = -1;	
V1SearchImp.matrix.city          = -1;	
V1SearchImp.matrix.state         = -1;	
V1SearchImp.matrix.zip           = -1;	
V1SearchImp.matrix.apinoadf      = -1;
V1SearchImp.matrix.verb          = -1;
V1SearchImp.matrix.TOCTarget     = -1;	

	
// Describe which field names you need to cast into other values
// specific to the API.
V1SearchImp.matrix.client          = "clientid";
V1SearchImp.matrix.menu            = "_menu";
V1SearchImp.matrix.originationCode = "ORIGINATION_CODE";	
V1SearchImp.matrix.search          = "query";
V1SearchImp.matrix.sort            = "newSortMode";
V1SearchImp.matrix.source          = "src";
V1SearchImp.matrix.uid             = "USER_ID";
V1SearchImp.matrix.pwd             = "PASSWORD";	
	
/**
 * This matric 
 */
V1SearchImp.submit = function(chunnel)
{
	// Preprocessor needs to convert generic after field 
	// to XLink's relativedate field
	chunnel = V1SearchImp._preprocessor(chunnel);

	var linker = V1SearchImp.getLink(chunnel);

	// prompt("",linker);

	// If no target, set the target for the same window.	
	if (!Truth.isTrue(chunnel.target))
	{
		chunnel.target = "_self";
	}
	
	// prompt("", linker)
	// And send it on its merry way
	var w = window.open(linker, chunnel.target, NEW_WINDOW_FEATURES); 

};

/**
 * Take any actions that need to be made on the MQ object before it gets
 * submitted to its specific API.
 */
V1SearchImp._preprocessor =  function(chunnel)
{
	if (Truth.isTrue(chunnel.pwd) || (chunnel.source.indexOf("SMRTLX") != -1))
	{
		chunnel.protocol = "https:";
		if (!Truth.isTrue(chunnel.get("LNAUTHSCHEME")))
		{
			chunnel.set("LNAUTHSCHEME", "C");
		}
	}
	
	if (!Truth.isTrue(chunnel.get("verb")))
	{
		chunnel.set("verb", V1SearchImp.DEFAULT_VERB);
	}
	
	return chunnel;
}

V1SearchImp.getLink = function(chunnel)
{
	var domain = V1SearchImp.DEFAULT_DOMAIN;
	
	if (chunnel.domain && chunnel.domain !== "") 
	{
		domain = chunnel.domain;
	}
	
	var action;
	
	if (Truth.isTrue(chunnel.override))
	{
		action = chunnel.override;
	}
	else
	{
		action = chunnel.protocol + "//" + domain + "/api.universe/" + chunnel.get("verb");
	}

	return action + "?" + SearchImplementor.getQueryString(chunnel, V1SearchImp.matrix);

};/**
 * MasterQuery Implementor for XLink.
 * @constructor
 * @private
 */
function XLinkImp()
{
	throw new Error("XLinkImp is a static class. Do not instantiate.");
}

XLinkImp.DEFAULT_DOMAIN = "www.lexis.com";
XLinkImp.DEFAULT_ZONE_DOMAIN = "web.lexis-nexis.com";
// XLinkImp.DEFAULT_DOMAIN = "cert-2610.lexis.com";


// Create API Matrix
// The matrix is used to cast object elements into those used by the API.
XLinkImp.matrix          = new Object();

// Filter out MQ fields that we don't want in the query string
XLinkImp.matrix.pwd      = -1;
XLinkImp.matrix.uid      = -1;
XLinkImp.matrix.domain   = -1;
XLinkImp.matrix.protocol = -1;

// Describe which field names you need to cast into other values
// specific to the API.
XLinkImp.matrix.originationCode = "ORIGINATION_CODE";
XLinkImp.matrix.sort            = "sortby";
XLinkImp.matrix.TOCTarget       = "target";
XLinkImp.matrix.authToken       = "uisToken";
	
/**
 * Takes a chunnel object and submits it. The last step in the journey
 * of a chunnel object before it becomes a LN search result.
 */
XLinkImp.submit = function(chunnel)
{
    if ((Truth.isTrue(chunnel.uid)) || (Truth.isTrue(chunnel.pwd)))
        chunnel = SearchImplementor.tokenize(chunnel);
	
//alert(SearchImplementor.getQueryString(chunnel, XLinkImp.matrix));
	// Preprocessor needs to convert generic after field 
	// to XLink's relativedate field
	XLinkImp._preprocessor(chunnel);
	var linker = XLinkImp.getLink(chunnel);
	// If no target, set the target for the same window.	
	if (!Truth.isTrue(chunnel.target))
	{
		chunnel.target = "_self";
	}
	
    // prompt("", linker)
	
	if (XLinkImp.useGet(chunnel)) 
	{
		var w = window.open(linker, chunnel.target, NEW_WINDOW_FEATURES); 
	}
	else
	{
		var f = "<form method='post' action='";
		f += linker;
		f += "' id='masterQueryDynaForm' name='masterQueryDynaForm' target='";
		f += chunnel.target;
		f += "'>";
		f += FormUtil.getHiddenFieldVal('USER_ID', chunnel.getUID());
		f += FormUtil.getHiddenFieldVal('PASSWORD', chunnel.getPWD());
		f += FormUtil.getHiddenFieldVal('LNAUTHSCHEME', 'CP');
		f += "</form>";

		SearchImplementor.submitDiv(f);
	}
	chunnel = null;
};

/**
 * Take any actions that need to be made on the MQ object before it gets
 * submitted to its specific API.
 */
XLinkImp._preprocessor =  function(chunnel)
{
	var relativedate = LNParser.convertAfterToRelative(chunnel.getAfter());
	chunnel.c_relativedate = relativedate;
	chunnel.after = "";
	
	if (Truth.isTrue(chunnel.zone) && !Truth.isTrue(chunnel.get("toclink")))
	{
		chunnel.set("toclink", "off");
	}
	
	if (Truth.isTrue(chunnel.zone) && !Truth.isTrue(chunnel.get("hnlink")))
	{
		chunnel.set("hnlink", "off");
	}
	
	if (Truth.isTrue(chunnel.pwd) || Truth.isTrue(chunnel.authToken))
	{
		chunnel.protocol = "https:";
	}
	return chunnel;
};

/**
 * Returns the link that is the target for the API call.
 * This can be used as the action for a form or as the location
 * for a called to window.open.
 *
 * The query string is return based upon the chunnel values filtered 
 * through the implementor's matrix
 */
XLinkImp.getLink = function(chunnel)
{
	var domain;
	
	if (chunnel.zone && chunnel.zone !== "") 
	{
		domain = XLinkImp.DEFAULT_ZONE_DOMAIN;
	}
	else
	{
	    domain = XLinkImp.DEFAULT_DOMAIN;
	}
	
	if (chunnel.domain && chunnel.domain !== "") 
	{
		domain = chunnel.domain;
	}
	
	var action
	
	if (Truth.isTrue(chunnel.override))
	{
		action = chunnel.override;
	}
	else
	{
		action = chunnel.protocol + "//" + domain + "/research/xlink";
	}
	return action + "?" + SearchImplementor.getQueryString(chunnel, XLinkImp.matrix);

};

/**
 * Should we use get or post. If there's a username/pwd use post.
 */
XLinkImp.useGet = function(chunnel)
{
	if (Truth.isTrue(chunnel.pwd) && Truth.isTrue(chunnel.uid)) 
	{
		return false;
	}
	return true;
}
/**
 * MasterQuery Implementor for Get & Print.
 * @constructor
 * @private
 */
function GPImp()
{
	throw new Error("GPImp is a static class. Do not instantiate.");
}

GPImp.DEFAULT_DOMAIN = "www3.lexis.com";
GPImp.DEFAULT_ZONE_DOMAIN = "web.lexis-nexis.com";
GPImp.DEFAULT_VERB         = "xlink.asp";

// GPImp.DEFAULT_DOMAIN = "cert-2610.lexis.com";


// Create API Matrix
// The matrix is used to cast object elements into those used by the API.
GPImp.matrix          = new Object();

// Filter out MQ fields that we don't want in the query string
GPImp.matrix.pwd      = -1;
GPImp.matrix.uid      = -1;
GPImp.matrix.domain   = -1;
GPImp.matrix.protocol = -1;
GPImp.matrix.verb     = -1;

// Describe which field names you need to cast into other values
// specific to the API.
GPImp.matrix.originationCode = "ORIGINATION_CODE";
GPImp.matrix.search          = "citations";
GPImp.matrix.authToken       = "uisToken";

	
/**
 * Takes a chunnel object and submits it. The last step in the journey
 * of a chunnel object before it becomes a LN search result.
 */
GPImp.submit = function(chunnel)
{
    if ((Truth.isTrue(chunnel.uid)) || (Truth.isTrue(chunnel.pwd)))
        chunnel = SearchImplementor.tokenize(chunnel);
//alert(SearchImplementor.getQueryString(chunnel, GPImp.matrix));
	GPImp._preprocessor(chunnel);
	var linker = GPImp.getLink(chunnel);
	// If no target, set the target for the same window.	
	if (!Truth.isTrue(chunnel.target))
	{
		chunnel.target = "_self";
	}
	// prompt("", linker)
	
	if (GPImp.useGet(chunnel)) 
	{
		var w = window.open(linker, chunnel.target, NEW_WINDOW_FEATURES); 
	}
	else
	{
		var f = "<form method='post' action='";
		f += linker;
		f += "' id='masterQueryDynaForm' name='masterQueryDynaForm' target='";
		f += chunnel.target;
		f += "'>";
		f += FormUtil.getHiddenFieldVal('userid', chunnel.getUID());
		f += FormUtil.getHiddenFieldVal('password', chunnel.getPWD());
		f += "</form>";

		SearchImplementor.submitDiv(f);
	}
	chunnel = null;
};

/**
 * Take any actions that need to be made on the MQ object before it gets
 * submitted to its specific API.
 */
GPImp._preprocessor =  function(chunnel)
{
	
	if (Truth.isTrue(chunnel.pwd) || Truth.isTrue(chunnel.authToken))
	{
		chunnel.protocol = "https:";
	}
    	
	return chunnel;
};

/**
 * Returns the link that is the target for the API call.
 * This can be used as the action for a form or as the location
 * for a called to window.open.
 *
 * The query string is returned based upon the chunnel values filtered 
 * through the implementor's matrix
 */
GPImp.getLink = function(chunnel)
{
	var domain;
	
	if (chunnel.zone && chunnel.zone !== "") 
	{
		domain = GPImp.DEFAULT_ZONE_DOMAIN;
	}
	else
	{
	    domain = GPImp.DEFAULT_DOMAIN;
	}
	
	if (chunnel.domain && chunnel.domain !== "") 
	{
		domain = chunnel.domain;
	}
	
	if (!Truth.isTrue(chunnel.get("verb")) && !Truth.isTrue(chunnel.get("Citations_List")))
	{
		chunnel.set("verb", GPImp.DEFAULT_VERB);
	}
	if (chunnel.get("verb").toLowerCase() == "submitsession.html")
	{
	    if (!Truth.isTrue(chunnel.get("seamlessSignon")))
	    {
		    chunnel.set("seamlessSignon", true);
	    }
	    if (!Truth.isTrue(chunnel.getMenu()))
	    {
		    chunnel.setMenu("WT1164");
	    }
	}
	var action
	
	if (Truth.isTrue(chunnel.override))
	{
		action = chunnel.override;
	}
	else
	{
		action = chunnel.protocol + "//" + domain + "/getandprint/" + chunnel.get("verb");
	}
	return action + "?" + SearchImplementor.getQueryString(chunnel, GPImp.matrix);

};

/**
 * Should we use get or post. If there's a username/pwd use post.
 */
GPImp.useGet = function(chunnel)
{
	if (Truth.isTrue(chunnel.pwd) && Truth.isTrue(chunnel.uid)) 
	{
		return false;
	}
	return true;
}
/**
 * Please use ppcmixed2/ppccpwd77 as id/pwd for uk/legal.
 *
 * http://www.lexisnexis.com/uk/legal/api/version1/sr?csi=267991&sr=police and legal&hd=t
 * @constructor
 * @private
 */
function UrlApiPubRecImp()
{
	throw new Error("UrlApiPubRecImp is a static class. Do not instantiate.");
}

UrlApiPubRecImp.DEBUG            = true;

UrlApiPubRecImp.DEFAULT_DOMAIN       = "www.lexisnexis.com";
UrlApiPubRecImp.DEFAULT_NEXIS_DOMAIN = "w3.nexis.com";
//UrlApiPubRecImp.DEFAULT_DOMAIN       = "cdc1-www.lexisnexis.com";
//UrlApiPubRecImp.DEFAULT_NEXIS_DOMAIN = "cdc1-www.lexisnexis.com";
UrlApiPubRecImp.DEFAULT_ADAPTION     = "uk";
UrlApiPubRecImp.DEFAULT_TYPE         = "legal";
UrlApiPubRecImp.DEFAULT_API_VERSION  = "api";
UrlApiPubRecImp.DEFAULT_VERB         = "sr";

// Create API Matrix
// The matrix is used to cast object elements into those used by the API.
UrlApiPubRecImp.matrix          = new Object();

// Filter out MQ fields that we don't want in the query string

UrlApiPubRecImp.matrix.adaption   = -1;
UrlApiPubRecImp.matrix.domain     = -1;
UrlApiPubRecImp.matrix.protocol   = -1;
UrlApiPubRecImp.matrix.type       = -1;
UrlApiPubRecImp.matrix.apiVersion = -1;
UrlApiPubRecImp.matrix.verb       = -1;
UrlApiPubRecImp.matrix.searchtype = -1;
UrlApiPubRecImp.matrix.TOCTarget     = -1;	

UrlApiPubRecImp.matrix.host       = -1;


UrlApiPubRecImp.matrix.pwd    = -1;
UrlApiPubRecImp.matrix.uid    = -1;
// UrlApiPubRecImp.matrix.pwd    = "pw";
// UrlApiPubRecImp.matrix.uid    = "ui";

// These fields don't exist in Rosetta
UrlApiPubRecImp.matrix.maxdocs  = -1;
UrlApiPubRecImp.matrix.zone     = -1;
UrlApiPubRecImp.matrix.citation = -1;
UrlApiPubRecImp.matrix.prod     = -1;


// Describe which field names you need to cast into other values
// specific to the API.

UrlApiPubRecImp.matrix.originationCode = "ORIGINATION_CODE";
UrlApiPubRecImp.matrix.client = "pi";
UrlApiPubRecImp.matrix.search = "query";

UrlApiPubRecImp.matrix.source = "csi";
UrlApiPubRecImp.matrix.sort   = "so";

// DOSSIER FIELDS
UrlApiPubRecImp.matrix.ticker = "tr";
UrlApiPubRecImp.matrix.name   = "nm";

// api.universe/search/searchform
UrlApiPubRecImp.matrix.id     = -1;


/**
 * Takes a chunnel object and submits it. The last step in the journey
 * of a chunnel object before it becomes a LN search result.
 */
UrlApiPubRecImp.submit = function(chunnel)
{
	try
	{

        
		// Preprocessor needs to convert generic after field 
		// to XLink's relativedate field
		UrlApiPubRecImp.preprocessor(chunnel);

		// If no target, set the target for the same window.	
		if (!Truth.isTrue(chunnel.target))
		{
			chunnel.target = "_self";
		}
		
		if (chunnel.get("verb") == "au")
		{
			UrlApiPubRecImp._submitAu(chunnel);
			return;
		}
		
		var linker = UrlApiPubRecImp.getLink(chunnel);
		
		if (!Truth.isTrue(chunnel.pwd) || Truth.isTrue(chunnel.override)) 
		{
			var w = window.open(linker, chunnel.target, NEW_WINDOW_FEATURES); 
		}
		else
		{
			var f = "<form method='post' action='";
			f += linker;
			f += "' id='masterQueryDynaForm' name='masterQueryDynaForm' target='";
			f += chunnel.target;
			f += "'>";
			f += FormUtil.getHiddenFieldVal('ui', chunnel.getUID());
			f += FormUtil.getHiddenFieldVal('pw', chunnel.getPWD());
			f += FormUtil.getHiddenFieldVal('rm', chunnel.get("rm"));
			f += "</form>";

			SearchImplementor.submitDiv(f);
		}
		
		chunnel = null;
	}
	catch(ex)
	{
		if (UrlApiPubRecImp.DEBUG)
		{
			alert(ex.message)
		}
	}
};

UrlApiPubRecImp.libfileToCSI = function(libfile)
{
	if (libfile.lastIndexOf(";") != -1) {
		var http = new HttpRequest();
		http.setTarget(MasterQuery.baseURL + "getCSI.asp");
		http.setForm(new URLBuilder("libfile", libfile))
		var csi = http.get();
		if (csi)
		{
			return csi;
		}		
	} 
	return libfile;
}

/**
 * Submit using the authentication verb
 */
UrlApiPubRecImp._submitAu =  function(chunnel)
{

    chunnel.setProtocol("https:")

	var f = "<form method='get' action='";
	f += UrlApiPubRecImp.getLink(chunnel);
	f += "' id='masterQueryDynaForm' name='masterQueryDynaForm' target='";
	f += chunnel.target;
	f += "'>";
	f += FormUtil.getHiddenFieldVal('ui', chunnel.getUID());
	f += FormUtil.getHiddenFieldVal('pw', chunnel.getPWD());
	// f += FormUtil.getHiddenFieldVal('rt', chunnel.get("rt"));
	// f += FormUtil.getHiddenFieldVal('rm', chunnel.get("rm"));
	// f += FormUtil.getHiddenFieldVal('pi', chunnel.getClient());
	
	f += "</form>";
	
	SearchImplementor.submitDiv(f);
}

UrlApiPubRecImp._submitSo =  function(chunnel)
{
	window.open(UrlApiPubRecImp.getVerbPath(chunnel), chunnel.target, NEW_WINDOW_FEATURES); 
}

/**
 * Take any actions that need to be made on the MQ object before it gets
 * submitted to its specific API.
 */
UrlApiPubRecImp.preprocessor =  function(chunnel)
{
    var stateList = new Array();
    //State Abbreviations
    stateList[0] = "AL";
	stateList[1] = "AK";
	stateList[2] = "AZ";
	stateList[3] = "AR";
	stateList[4] = "CA";
	stateList[5] = "CO";
	stateList[6] = "CT";
	stateList[7] = "DE";
	stateList[8] = "DC";
	stateList[9] = "FL";
	stateList[10] = "GA";
	stateList[11] = "GU";
	stateList[12] = "HI";
	stateList[13] = "ID";
	stateList[14] = "IL";
	stateList[15] = "IN";
	stateList[16] = "IA";
	stateList[17] = "KS";
	stateList[18] = "KY";
	stateList[19] = "LA";
	stateList[20] = "ME";
	stateList[21] = "MD";
	stateList[22] = "MA";
	stateList[23] = "MI";
	stateList[24] = "MN";
	stateList[25] = "MS";
	stateList[26] = "MO";
	stateList[27] = "MT";
	stateList[28] = "NE";
	stateList[29] = "NV";
	stateList[30] = "NH";
	stateList[31] = "NJ";
	stateList[32] = "NM";
	stateList[33] = "NY";
	stateList[34] = "NC";
	stateList[35] = "ND";
	stateList[36] = "OH";
	stateList[37] = "OK";
	stateList[38] = "OR";
	stateList[39] = "PA";
	stateList[40] = "PR";
	stateList[41] = "RI";
	stateList[42] = "SC";
	stateList[43] = "SD";
	stateList[44] = "TN";
	stateList[45] = "TX";
	stateList[46] = "UT";
	stateList[47] = "VT";
	stateList[48] = "VA";
	stateList[49] = "VI";
	stateList[50] = "WA";
	stateList[51] = "WV";
	stateList[52] = "WI";
	stateList[53] = "WY";

    var stateSourceList = new Array(new Array(54), new Array(54));
    //Old Person Sources
    stateSourceList[0][0] = "314663";
    stateSourceList[0][1] = "314658";
    stateSourceList[0][2] = "314669";
    stateSourceList[0][3] = "314666";
    stateSourceList[0][4] = "314673";
    stateSourceList[0][5] = "314675";
    stateSourceList[0][6] = "314678";
    stateSourceList[0][7] = "314684";
    stateSourceList[0][8] = "314681";
    stateSourceList[0][9] = "314687";
    stateSourceList[0][10] = "314690";
    stateSourceList[0][11] = "314692";
    stateSourceList[0][12] = "314695";
    stateSourceList[0][13] = "314711";
    stateSourceList[0][14] = "314713";
    stateSourceList[0][15] = "314715";
    stateSourceList[0][16] = "314709";
    stateSourceList[0][17] = "314717";
    stateSourceList[0][18] = "314719";
    stateSourceList[0][19] = "314721";
    stateSourceList[0][20] = "314727";
    stateSourceList[0][21] = "314725";
    stateSourceList[0][22] = "314723";
    stateSourceList[0][23] = "314729";
    stateSourceList[0][24] = "314731";
    stateSourceList[0][25] = "314736";
    stateSourceList[0][26] = "314734";
    stateSourceList[0][27] = "314821";
    stateSourceList[0][28] = "314748";
    stateSourceList[0][29] = "314758";
    stateSourceList[0][30] = "314751";
    stateSourceList[0][31] = "314753";
    stateSourceList[0][32] = "314756";
    stateSourceList[0][33] = "314761";
    stateSourceList[0][34] = "314742";
    stateSourceList[0][35] = "314745";
    stateSourceList[0][36] = "314763";
    stateSourceList[0][37] = "314765";
    stateSourceList[0][38] = "314767";
    stateSourceList[0][39] = "314769";
    stateSourceList[0][40] = "314772";
    stateSourceList[0][41] = "314829";
    stateSourceList[0][42] = "314777";
    stateSourceList[0][43] = "314782";
    stateSourceList[0][44] = "314786";
    stateSourceList[0][45] = "314788";
    stateSourceList[0][46] = "314790";
    stateSourceList[0][47] = "314796";
    stateSourceList[0][48] = "314792";
    stateSourceList[0][49] = "314794";
    stateSourceList[0][50] = "314798";
    stateSourceList[0][51] = "314802";
    stateSourceList[0][52] = "314800";
    stateSourceList[0][53] = "314804";

    //Old Business sources
    stateSourceList[1][0] = "314661";
    stateSourceList[1][1] = "314652";
    stateSourceList[1][2] = "314668";
    stateSourceList[1][3] = "314665";
    stateSourceList[1][4] = "314671";
    stateSourceList[1][5] = "314674";
    stateSourceList[1][6] = "314677";
    stateSourceList[1][7] = "314683";
    stateSourceList[1][8] = "314680";
    stateSourceList[1][9] = "314685";
    stateSourceList[1][10] = "314688";
    stateSourceList[1][11] = "314691";
    stateSourceList[1][12] = "314694";
    stateSourceList[1][13] = "314710";
    stateSourceList[1][14] = "314712";
    stateSourceList[1][15] = "314714";
    stateSourceList[1][16] = "314708";
    stateSourceList[1][17] = "314716";
    stateSourceList[1][18] = "314718";
    stateSourceList[1][19] = "314720";
    stateSourceList[1][20] = "314726";
    stateSourceList[1][21] = "314724";
    stateSourceList[1][22] = "314722";
    stateSourceList[1][23] = "314728";
    stateSourceList[1][24] = "314730";
    stateSourceList[1][25] = "314735";
    stateSourceList[1][26] = "314733";
    stateSourceList[1][27] = "314738";
    stateSourceList[1][28] = "314747";
    stateSourceList[1][29] = "314757";
    stateSourceList[1][30] = "314750";
    stateSourceList[1][31] = "314752";
    stateSourceList[1][32] = "314754";
    stateSourceList[1][33] = "314760";
    stateSourceList[1][34] = "314739";
    stateSourceList[1][35] = "314743";
    stateSourceList[1][36] = "314762";
    stateSourceList[1][37] = "314764";
    stateSourceList[1][38] = "314766";
    stateSourceList[1][39] = "314768";
    stateSourceList[1][40] = "314770";
    stateSourceList[1][41] = "314773";
    stateSourceList[1][42] = "314775";
    stateSourceList[1][43] = "314780";
    stateSourceList[1][44] = "314783";
    stateSourceList[1][45] = "314787";
    stateSourceList[1][46] = "314789";
    stateSourceList[1][47] = "314795";
    stateSourceList[1][48] = "314791";
    stateSourceList[1][49] = "314793";
    stateSourceList[1][50] = "314797";
    stateSourceList[1][51] = "314801";
    stateSourceList[1][52] = "314799";
    stateSourceList[1][53] = "314803";

    for (var i=0; i<54;i++)
    {
        if ((chunnel.getSource() == stateSourceList[0][i]) || (chunnel.getSource() == stateSourceList[1][i]))
            chunnel.set("State", stateList[i]);
    }
    
	if (!Truth.isTrue(chunnel.get("glba")))
	{
		chunnel.set("glba", "7");
	}
	if (!Truth.isTrue(chunnel.get("dppa")))
	{
		chunnel.set("dppa", "7");
	}
	if (!Truth.isTrue(chunnel.get("goto")))
	{
		chunnel.set("goto", "results");
	}
	if (!Truth.isTrue(chunnel.get("adaption")))
	{
		chunnel.set("adaption", UrlApiPubRecImp.DEFAULT_ADAPTION);
	}
	
	format = "us";
	
	if (chunnel.get("adaption") != "nexis")
	{
		format = "uk";
	}

	chunnel = LNParser.convertDateToQuery(chunnel, format);
	
	if (Truth.isTrue(chunnel.getSort()))
	{
		chunnel.setSort("da");
	}
	
	if (Truth.isTrue(chunnel.pwd))
	{
		// not working for auth
		// chunnel.protocol = "https:";
	}
	
	if (!Truth.isTrue(chunnel.get("type")))
	{
		chunnel.set("type", UrlApiPubRecImp.DEFAULT_TYPE);
	}
	
	if (!Truth.isTrue(chunnel.get("verb")))
	{
		chunnel.set("verb", UrlApiPubRecImp.DEFAULT_VERB);
	}
	
	//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
	// Auto-convert libfile to CSI numbers
	
	chunnel.setSource(UrlApiPubRecImp.libfileToCSI(chunnel.getSource()));
	
	//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
	// LEXSEE & LEXSTAT
	
	var type = chunnel.getSearchtype();
	
	switch(type)
	{
		case "get":
		case "lexsee":
		case "lxe":
		case "lexstat":
		
			// Make sure that the source isn't already set
			if (!Truth.isTrue(chunnel.getSource())) 
			{
				// http://psc744:6060/ssdf/guide/dynmff/bin/dynmff.pl?type=library&csi=12660&lvl=3
				// Source: MEGA
				// chunnel.setSource("12660")
				chunnel.setSource("138150")
				// 
			}
			break;
	
		default:
			break;
	}
	
	//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
	// CUI BUILDER CITATION
	
	// &citation=1+us+1
	if (Truth.isTrue(chunnel.get("citation")))
	{
		if (!Truth.isTrue(chunnel.getSource()) && !Truth.isTrue(chunnel.getSearch()))
		{
			chunnel.setSearch(chunnel.get("citation"))
			chunnel.setSource("12660")
		} 
	}
	
	//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
	// Nexis searchforms
	
	if (chunnel.get("id")) 
	{

		chunnel.set("verb", "sf")
		
		switch(chunnel.get("id"))
		{
			// Power Search
			case "-99":
				chunnel.set("sfi", "US00NBGenSrch");
				break;
			// US Reports // Company Profile Page
			case "1928":
				chunnel.set("sfi", "US02NBCmpSrch");
				break;
			// SEC Filings
			case "1940":
			case "2378":
				chunnel.set("sfi", "US02NBSECFilSrch");
				break;
			// Mergers & Acquisitions 
			case "1945":
				chunnel.set("sfi", "US02NBMergAcqSrch");
				break;
			// Business Locator/Assets
			case "1930":
				chunnel.set("sfi", "US04NBBusLocSrch");
				break;
			// Asset Locator
			case "2515":
				chunnel.set("sfi", "US04NBAssetLocSrch");
				break;
			// Bankruptcy Filings
			case "1375":
			case "2517":
				chunnel.set("sfi", "US04NBBankrupSrch");
				break;	
			// Judgments
			case "2519":
				chunnel.set("sfi", "US04NBJudLiensSrch");
				break;
			// Licenses
			case "2522":
				chunnel.set("sfi", "US04NBLicensesSrch");
				break;
			// Civil &amp; Criminal Filings
			case "2523":
				chunnel.set("sfi", "US04NBCivCrimSrch");
				break;	
			// D&B
			case "2524":
				chunnel.set("sfi", "US02NBDunBradSrch");
				break;
			// Motor Vehicles Registrations 
			case "2727":
				chunnel.set("sfi", "US04NBDriverSrch");
				break;
			// Motor Vehicle Registrations
			case "2729":
				chunnel.set("sfi", "US04NBMotVehSrch");
				break;
			// General News 
			case "2888":
				chunnel.set("sfi", "US01NBSimplSrch");
				break;
			// Edgar - SEC Real Time Filings
			case "2911":
				chunnel.set("sfi", "US02NBEdgarSrch");
				break;
		}
	}

	return chunnel;
};




/**
 * Returns the link that is the target for the API call.
 * This can be used as the action for a form or as the location
 * for a called to window.open.
 *
 * The query string is return based upon the chunnel values filtered 
 * through the implementor's matrix
 */
UrlApiPubRecImp.getLink = function(chunnel)
{
    var xml
    xml = UrlApiPubRecImp.getXML(chunnel);
    chunnel.setSearch(xml);
    chunnel.set("ssl", "t");

	var qs = SearchImplementor.getQueryString(chunnel, UrlApiPubRecImp.matrix);
	
	if (Truth.isTrue(qs))
	{
		return UrlApiPubRecImp.getVerbPath(chunnel) + "?" + qs;
	}
	else
	{
		return UrlApiPubRecImp.getVerbPath(chunnel);
	}
};

/**
 * Returns the link that is the target for the API call.
 * This can be used as the action for a form or as the location
 * for a called to window.open.
 *
 * The query string is return based upon the chunnel values filtered 
 * through the implementor's matrix
 */
UrlApiPubRecImp.getVerbPath = function(chunnel)
{
	var domain = UrlApiPubRecImp.DEFAULT_DOMAIN;

	if (chunnel.domain && chunnel.domain !== "") 
	{
		domain = chunnel.domain;
	}
	
	if (chunnel.domain !== "" && chunnel.get("adaption") == "nexis")
	{
		domain = UrlApiPubRecImp.DEFAULT_NEXIS_DOMAIN;
	}

	if (chunnel.domain && chunnel.domain !== "") 
	{
		domain = chunnel.domain;
	}
	
	if (Truth.isTrue(chunnel.override))
	{
		return chunnel.override;
	}
	else
	{
		var adaption = chunnel.get("adaption")
		
		if (adaption == "nexis")
		{
			adaption = "new"
		}
		
	    chunnel.setProtocol("https:");

		var adLink = chunnel.protocol + "//" + domain + "/" + adaption;
	
		if (chunnel.get("adaption") != "nexis")
		{
			adLink += "/" + chunnel.get("type")
		}
		
		if (chunnel.get("verb") == "home")
		{
			return adLink + "/home/home.do";
		}
		else
		{
			var apiVersion = UrlApiPubRecImp.DEFAULT_API_VERSION;
			
			if (chunnel.get("verb") == "accessGW") {
				var apiVersion = "api";
			}
			
			if (Truth.isTrue(chunnel.get("apiVersion")))
			{
				apiVersion = chunnel.get("apiVersion");
			}

			return adLink + "/" + apiVersion + "/" + chunnel.get("verb");	
		}
	}
};

UrlApiPubRecImp.getXML = function(chunnel)
{
	var xml = '<fieldList>';
	xml += UrlApiPubRecImp.checkPRMAField("Fname", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Lname", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Mname", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Street", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("City", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Zip", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Radius", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Phone", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("SSN", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("DOB", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("AgeLow", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("AgeHigh", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Terms", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("aliasLName", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("RelFName1", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("RelFname2", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("RelFName2", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("PrevCity", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("PrevState1", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("PrevState2", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("UsePhonetics", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Cname", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("FEIN", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("ParcelId", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Vin", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Plate", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Make", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Model", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("License", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Hull", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Vname", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("OfficialNumber", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("AircraftNumber", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("CaseNumber", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("FilingDate", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Status", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("PRMAType", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Assets", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Liabilities", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("DocumentNumber", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("AccNumber", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("LicNumber", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("FullName", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("OtherName", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Country", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("County", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("FilingNumber", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("FilingJurisdiction", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("PRMADomain", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("IssuedState", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("Trade", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("LoanAmount", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("LoanAmountOperator", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("LoanAmountHighValue", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("SalePrice", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("SalePriceOperator", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("SalePriceHighValue", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("LandValue", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("LandValueOperator", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("LandValueHighValue", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("TaxAmount", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("TaxAmountOperator", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("TaxAmountHighValue", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("PRMASource", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("BooleanMode", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("UseNicknames", chunnel);
    xml += UrlApiPubRecImp.checkPRMAField("StrictMatch", chunnel);

    if ((xml == '<fieldList>') || (xml == '<fieldList><field name="BooleanMode">True</field>'))
    {
        chunnel.set("goto", "form");
    }

    xml += UrlApiPubRecImp.checkPRMAField("State", chunnel);

    //alert(xml + '</fieldList>');

    return xml + '</fieldList>';
};

UrlApiPubRecImp.checkPRMAField = function(name, chunnel)
{
    var booleanSourceList = new Array(24);
    //Sources which accept the Terms field
    booleanSourceList[0] = "314679";
    booleanSourceList[1] = "314682";
    booleanSourceList[2] = "314689";
    booleanSourceList[3] = "314023";
    booleanSourceList[4] = "314696";
    booleanSourceList[5] = "314697";
    booleanSourceList[6] = "314699";
    booleanSourceList[7] = "314700";
    booleanSourceList[8] = "314737";
    booleanSourceList[9] = "314827";
    booleanSourceList[10] = "314749";
    booleanSourceList[11] = "314825";
    booleanSourceList[12] = "314784";
    booleanSourceList[13] = "314785";
    booleanSourceList[14] = "314813";
    booleanSourceList[15] = "314814";
    booleanSourceList[16] = "314816";
    booleanSourceList[17] = "314817";
    booleanSourceList[18] = "314844";
    booleanSourceList[19] = "314819";
    booleanSourceList[20] = "314820";
    booleanSourceList[21] = "314822";
    booleanSourceList[22] = "314823";
    booleanSourceList[23] = "314473";

    var isBoolSource = false;
    
    for (var j=0; j<24;j++)
    {
        if ((chunnel.getSource() == booleanSourceList[j]))
        {
            isBoolSource = true;
            break;
        }
    }
    if (!isBoolSource && (name == "Terms"))
    {
   	    eval("UrlApiPubRecImp.matrix." + name + "     = -1;")
        return "";
    }
            
    var finalName = name;

    if (finalName.search("PRMA") == 0)
        finalName = finalName.slice(4);
    
    var val;
    val = "";
    if (Truth.isTrue(chunnel.get(name))) 
    {
	    val = UrlApiPubRecImp.getPRMAField(chunnel.get(name), finalName);
	    eval("UrlApiPubRecImp.matrix." + name + "     = -1;")
    }
    if (Truth.isTrue(chunnel.get(name.toLowerCase()))) 
    {
	    val = UrlApiPubRecImp.getPRMAField(chunnel.get(name.toLowerCase()), finalName);
	    eval("UrlApiPubRecImp.matrix." + name.toLowerCase() + "     = -1;")
    }
    if (Truth.isTrue(chunnel.get(name.toUpperCase()))) 
    {
	    val = UrlApiPubRecImp.getPRMAField(chunnel.get(name.toUpperCase()), finalName);
	    eval("UrlApiPubRecImp.matrix." + name.toUpperCase() + "     = -1;")
    }
    if ((name.toUpperCase() == "TERMS") && (val != ""))
    {
	    val = val + UrlApiPubRecImp.getPRMAField("True", "BooleanMode");
	    UrlApiPubRecImp.matrix.BooleanMode     = -1;
    }

    return val
}
UrlApiPubRecImp.getPRMAField = function(value, name)
{
    if (name != "DOB" && name != "LoanAmountOperator" && name != "TaxAmountOperator" && name != "LandValueOperator" && name != "SalePriceOperator")
	    value = value.replace(/[^a-zA-Z0-9*!_:/()\-]/g, " ");
	
	return '<field name="' + name + '">' + value + '</field>';

};/**
 * @constructor
 * @private
 */
function XLinkPubRecImp()
{
	throw new Error("XLinkPubRecImp is a static class. Do not instantiate.");
}

// CONSTANTS
XLinkPubRecImp.DEFAULT_DOMAIN          = "www.lexis.com";
//XLinkPubRecImp.DEFAULT_DOMAIN          = "cert-2610.lexis.com";
// XLinkPubRecImp.DEFAULT_DOMAIN          = "wmitzjx.lexis.com";
XLinkPubRecImp.DEFAULT_VERSION         = "1.0";

// Create API Matrix
// The matrix is used to cast object elements into those used by the API.
XLinkPubRecImp.matrix          = new Object();

// Filter out MQ fields that we don't want in the query string
XLinkPubRecImp.matrix.pwd           = -1;
XLinkPubRecImp.matrix.uid           = -1;
XLinkPubRecImp.matrix.domain        = -1;
XLinkPubRecImp.matrix.protocol      = -1;

XLinkPubRecImp.matrix.lastName      = -1;
XLinkPubRecImp.matrix.lName      = -1;
XLinkPubRecImp.matrix.firstName     = -1;
XLinkPubRecImp.matrix.fName      = -1;
XLinkPubRecImp.matrix.companyName   = -1;
XLinkPubRecImp.matrix.ssn           = -1;
XLinkPubRecImp.matrix.streetAddress = -1;
XLinkPubRecImp.matrix.state         = -1;
XLinkPubRecImp.matrix.zip           = -1;
XLinkPubRecImp.matrix.telephone     = -1;
XLinkPubRecImp.matrix.birthDate     = -1;
XLinkPubRecImp.matrix.searchRadius  = -1;
XLinkPubRecImp.matrix.TOCTarget     = -1;
XLinkPubRecImp.matrix.authToken       = "uisToken";

// Describe which field names you need to cast into other values
// specific to the API.
XLinkPubRecImp.matrix.originationCode = "ORIGINATION_CODE";
	
/**
 * This matric 
 */
XLinkPubRecImp.submit = function(chunnel)
{
    if ((Truth.isTrue(chunnel.uid)) || (Truth.isTrue(chunnel.pwd)))
        chunnel = SearchImplementor.tokenize(chunnel);

	// Preprocessor needs to convert generic after field 
	// to XLink's relativedate field
	XLinkPubRecImp._preprocessor(chunnel);

	if (!Truth.isTrue(chunnel.version))
	{
		chunnel.version = XLinkPubRecImp.DEFAULT_VERSION;
	}
	// If no target, set the target for the same window.	
	if (!Truth.isTrue(chunnel.target))
	{
		chunnel.target = "_self";
	}
	
	// Get the XML
	var xml;
    xml = XLinkPubRecImp.getXML(chunnel);
	
	chunnel.setSearch("");
	chunnel.setMenu("");
	// chunnel.setSource("");
	
	// chunnel.set("mj", "");
	// chunnel.setMenu("MIDDLEWARE_CODE", "");
	
	var linker = XLinkPubRecImp.getLink(chunnel);
	

	var f = "<form method='post' action='";
	f += linker;
	f += "' id='masterQueryDynaForm' name='masterQueryDynaForm' target='"
	f += chunnel.target
	f += "'>";
	
	f += FormUtil.getHiddenFieldVal('USER_ID', chunnel.getUID());
	f += FormUtil.getHiddenFieldVal('PASSWORD', chunnel.getPWD());
	f += FormUtil.getHiddenFieldVal('LNAUTHSCHEME', 'CP');
	f += FormUtil.getHiddenFieldVal('search', xml);

	f += "</form>";

	var diver = document.getElementById("masterQueryDynaFormDiv");
	
	// Only create a new div if the existing div doesn't exist
	if (diver == null)
	{
		diver = document.createElement("div");
		diver.id = "masterQueryDynaFormDiv"
	}
	
	diver.innerHTML = f;
	document.body.appendChild(diver);
	
	var dForm = document.getElementById("masterQueryDynaForm");

	// prompt("", linker)

	dForm.submit();

	
	chunnel = null;
};

/**
 * Take any actions that need to be made on the MQ object before it gets
 * submitted to its specific API.
 */
XLinkPubRecImp._preprocessor =  function(chunnel)
{
    var stateList = new Array();
    //State Abbreviations
    stateList[0] = "AL";
	stateList[1] = "AK";
	stateList[2] = "AZ";
	stateList[3] = "AR";
	stateList[4] = "CA";
	stateList[5] = "CO";
	stateList[6] = "CT";
	stateList[7] = "DE";
	stateList[8] = "DC";
	stateList[9] = "FL";
	stateList[10] = "GA";
	stateList[11] = "GU";
	stateList[12] = "HI";
	stateList[13] = "ID";
	stateList[14] = "IL";
	stateList[15] = "IN";
	stateList[16] = "IA";
	stateList[17] = "KS";
	stateList[18] = "KY";
	stateList[19] = "LA";
	stateList[20] = "ME";
	stateList[21] = "MD";
	stateList[22] = "MA";
	stateList[23] = "MI";
	stateList[24] = "MN";
	stateList[25] = "MS";
	stateList[26] = "MO";
	stateList[27] = "MT";
	stateList[28] = "NE";
	stateList[29] = "NV";
	stateList[30] = "NH";
	stateList[31] = "NJ";
	stateList[32] = "NM";
	stateList[33] = "NY";
	stateList[34] = "NC";
	stateList[35] = "ND";
	stateList[36] = "OH";
	stateList[37] = "OK";
	stateList[38] = "OR";
	stateList[39] = "PA";
	stateList[40] = "PR";
	stateList[41] = "RI";
	stateList[42] = "SC";
	stateList[43] = "SD";
	stateList[44] = "TN";
	stateList[45] = "TX";
	stateList[46] = "UT";
	stateList[47] = "VT";
	stateList[48] = "VA";
	stateList[49] = "VI";
	stateList[50] = "WA";
	stateList[51] = "WV";
	stateList[52] = "WI";
	stateList[53] = "WY";

    var stateSourceList = new Array(new Array(54), new Array(54));
    //Old Person Sources
    stateSourceList[0][0] = "314663";
    stateSourceList[0][1] = "314658";
    stateSourceList[0][2] = "314669";
    stateSourceList[0][3] = "314666";
    stateSourceList[0][4] = "314673";
    stateSourceList[0][5] = "314675";
    stateSourceList[0][6] = "314678";
    stateSourceList[0][7] = "314684";
    stateSourceList[0][8] = "314681";
    stateSourceList[0][9] = "314687";
    stateSourceList[0][10] = "314690";
    stateSourceList[0][11] = "314692";
    stateSourceList[0][12] = "314695";
    stateSourceList[0][13] = "314711";
    stateSourceList[0][14] = "314713";
    stateSourceList[0][15] = "314715";
    stateSourceList[0][16] = "314709";
    stateSourceList[0][17] = "314717";
    stateSourceList[0][18] = "314719";
    stateSourceList[0][19] = "314721";
    stateSourceList[0][20] = "314727";
    stateSourceList[0][21] = "314725";
    stateSourceList[0][22] = "314723";
    stateSourceList[0][23] = "314729";
    stateSourceList[0][24] = "314731";
    stateSourceList[0][25] = "314736";
    stateSourceList[0][26] = "314734";
    stateSourceList[0][27] = "314821";
    stateSourceList[0][28] = "314748";
    stateSourceList[0][29] = "314758";
    stateSourceList[0][30] = "314751";
    stateSourceList[0][31] = "314753";
    stateSourceList[0][32] = "314756";
    stateSourceList[0][33] = "314761";
    stateSourceList[0][34] = "314742";
    stateSourceList[0][35] = "314745";
    stateSourceList[0][36] = "314763";
    stateSourceList[0][37] = "314765";
    stateSourceList[0][38] = "314767";
    stateSourceList[0][39] = "314769";
    stateSourceList[0][40] = "314772";
    stateSourceList[0][41] = "314829";
    stateSourceList[0][42] = "314777";
    stateSourceList[0][43] = "314782";
    stateSourceList[0][44] = "314786";
    stateSourceList[0][45] = "314788";
    stateSourceList[0][46] = "314790";
    stateSourceList[0][47] = "314796";
    stateSourceList[0][48] = "314792";
    stateSourceList[0][49] = "314794";
    stateSourceList[0][50] = "314798";
    stateSourceList[0][51] = "314802";
    stateSourceList[0][52] = "314800";
    stateSourceList[0][53] = "314804";

    //Old Business sources
    stateSourceList[1][0] = "314661";
    stateSourceList[1][1] = "314652";
    stateSourceList[1][2] = "314668";
    stateSourceList[1][3] = "314665";
    stateSourceList[1][4] = "314671";
    stateSourceList[1][5] = "314674";
    stateSourceList[1][6] = "314677";
    stateSourceList[1][7] = "314683";
    stateSourceList[1][8] = "314680";
    stateSourceList[1][9] = "314685";
    stateSourceList[1][10] = "314688";
    stateSourceList[1][11] = "314691";
    stateSourceList[1][12] = "314694";
    stateSourceList[1][13] = "314710";
    stateSourceList[1][14] = "314712";
    stateSourceList[1][15] = "314714";
    stateSourceList[1][16] = "314708";
    stateSourceList[1][17] = "314716";
    stateSourceList[1][18] = "314718";
    stateSourceList[1][19] = "314720";
    stateSourceList[1][20] = "314726";
    stateSourceList[1][21] = "314724";
    stateSourceList[1][22] = "314722";
    stateSourceList[1][23] = "314728";
    stateSourceList[1][24] = "314730";
    stateSourceList[1][25] = "314735";
    stateSourceList[1][26] = "314733";
    stateSourceList[1][27] = "314738";
    stateSourceList[1][28] = "314747";
    stateSourceList[1][29] = "314757";
    stateSourceList[1][30] = "314750";
    stateSourceList[1][31] = "314752";
    stateSourceList[1][32] = "314754";
    stateSourceList[1][33] = "314760";
    stateSourceList[1][34] = "314739";
    stateSourceList[1][35] = "314743";
    stateSourceList[1][36] = "314762";
    stateSourceList[1][37] = "314764";
    stateSourceList[1][38] = "314766";
    stateSourceList[1][39] = "314768";
    stateSourceList[1][40] = "314770";
    stateSourceList[1][41] = "314773";
    stateSourceList[1][42] = "314775";
    stateSourceList[1][43] = "314780";
    stateSourceList[1][44] = "314783";
    stateSourceList[1][45] = "314787";
    stateSourceList[1][46] = "314789";
    stateSourceList[1][47] = "314795";
    stateSourceList[1][48] = "314791";
    stateSourceList[1][49] = "314793";
    stateSourceList[1][50] = "314797";
    stateSourceList[1][51] = "314801";
    stateSourceList[1][52] = "314799";
    stateSourceList[1][53] = "314803";

    for (var i=0; i<54;i++)
    {
        if ((chunnel.getSource() == stateSourceList[0][i]) || (chunnel.getSource() == stateSourceList[1][i]))
            chunnel.set("State", stateList[i]);
    }

	var relativedate = LNParser.convertAfterToRelative(chunnel.getAfter());
	chunnel.c_relativedate = relativedate;
	chunnel.after = "";
	chunnel.setSearchtype("prma");

	if (!Truth.isTrue(chunnel.get("glba")))
	{
		chunnel.set("glba", "7");
	}
	if (!Truth.isTrue(chunnel.get("dppa")))
	{
		chunnel.set("dppa", "7");
	}
	if (Truth.isTrue(chunnel.pwd) || Truth.isTrue(chunnel.authToken))
	{
		chunnel.protocol = "https:";
	}
	return chunnel;
}

XLinkPubRecImp.getLinkWithXML = function(chunnel)
{
    var xml;
	xml = XLinkPubRecImp.getXML(chunnel);
	
	return XLinkPubRecImp.getLink(chunnel) + "&search=" + escape(xml);
};

XLinkPubRecImp.getLink = function(chunnel)
{
	var domain = XLinkPubRecImp.DEFAULT_DOMAIN;
	
	if (chunnel.domain && chunnel.domain !== "") 
	{
		domain = chunnel.domain;
	}
	
	var action
	
	if (Truth.isTrue(chunnel.override))
	{
		action = chunnel.override
	}
	else
	{
		action = chunnel.protocol + "//" + domain + "/research/xlink";
	}

	return action + "?" + SearchImplementor.getQueryString(chunnel, XLinkPubRecImp.matrix);

};

XLinkPubRecImp.getXML = function(chunnel)
{
	var xml = '<fieldList>';
	
	xml += XLinkPubRecImp.checkPRMAField("firstName", "Fname", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("Fname", "Fname", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("lastName", "Lname", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("Lname", "Lname", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("middleName", "Mname", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("Mname", "Mname", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("streetAddress", "Street", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("Street", "Street", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("City", "City", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("Zip", "Zip", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("searchRadius", "Radius", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("Radius", "Radius", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("telephone", "Phone", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("Phone", "Phone", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("Plate", "Plate", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("License", "License", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("FilingNumber", "FilingNumber", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("CaseNumber", "CaseNumber", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("SSN", "SSN", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("birthDate", "DOB", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("DOB", "DOB", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("AgeLow", "AgeLow", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("AgeHigh", "AgeHigh", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("Terms", "Terms", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("aliasFName", "aliasFName", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("aliasLName", "aliasLName", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("RelFName1", "RelFName1", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("RelFName2", "RelFName2", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("PrevCity", "PrevCity", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("PrevState1", "PrevState1", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("PrevState2", "PrevState2", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("companyName", "Cname", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("Cname", "Cname", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("FEIN", "FEIN", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("LoanAmount", "LoanAmount", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("LoanAmountOperator", "LoanAmountOperator", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("LoanAmountHighValue", "LoanAmountHighValue", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("SalePrice", "SalePrice", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("SalePriceOperator", "SalePriceOperator", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("SalePriceHighValue", "SalePriceHighValue", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("LandValue", "LandValue", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("LandValueOperator", "LandValueOperator", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("LandValueHighValue", "LandValueHighValue", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("TaxAmount", "TaxAmount", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("TaxAmountOperator", "TaxAmountOperator", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("TaxAmountHighValue", "TaxAmountHighValue", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("PRMASource", "Source", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("BooleanMode", "BooleanMode", chunnel);
	xml += XLinkPubRecImp.checkPRMAField("UseNicknames", "UseNicknames", chunnel);
	

    if (xml == '<fieldList>')
    {
        chunnel.set("autosubmit", "false");
    }
	xml += XLinkPubRecImp.checkPRMAField("State", "State", chunnel);


    //alert(xml + '</fieldList>');

    return xml + '</fieldList>';
};

XLinkPubRecImp.checkPRMAField = function(name, finalName, chunnel)
{
    var booleanSourceList = new Array(24);
    //Sources which accept the Terms field
    booleanSourceList[0] = "314679";
    booleanSourceList[1] = "314682";
    booleanSourceList[2] = "314689";
    booleanSourceList[3] = "314023";
    booleanSourceList[4] = "314696";
    booleanSourceList[5] = "314697";
    booleanSourceList[6] = "314699";
    booleanSourceList[7] = "314700";
    booleanSourceList[8] = "314737";
    booleanSourceList[9] = "314827";
    booleanSourceList[10] = "314749";
    booleanSourceList[11] = "314825";
    booleanSourceList[12] = "314784";
    booleanSourceList[13] = "314785";
    booleanSourceList[14] = "314813";
    booleanSourceList[15] = "314814";
    booleanSourceList[16] = "314816";
    booleanSourceList[17] = "314817";
    booleanSourceList[18] = "314844";
    booleanSourceList[19] = "314819";
    booleanSourceList[20] = "314820";
    booleanSourceList[21] = "314822";
    booleanSourceList[22] = "314823";
    booleanSourceList[23] = "314473";

    var isBoolSource = false;
    for (var i=0; i<24;i++)
    {
        if ((chunnel.getSource() == booleanSourceList[i]))
            isBoolSource = true;
    }
    if (!isBoolSource && (name == "Terms"))
    {
   	    eval("XLinkPubRecImp.matrix." + name + "     = -1;")
        return "";
    }
       
    var val;
    val = "";
    if (Truth.isTrue(chunnel.get(name))) 
    {
	    val = XLinkPubRecImp.getPRMAField(chunnel.get(name), finalName);
	    eval("XLinkPubRecImp.matrix." + name + "     = -1;")
    }
    if (Truth.isTrue(chunnel.get(name.toLowerCase()))) 
    {
	    val = XLinkPubRecImp.getPRMAField(chunnel.get(name.toLowerCase()), finalName);
	    eval("XLinkPubRecImp.matrix." + name.toLowerCase() + "     = -1;")
    }
    if (Truth.isTrue(chunnel.get(name.toUpperCase()))) 
    {
	    val = XLinkPubRecImp.getPRMAField(chunnel.get(name.toUpperCase()), finalName);
	    eval("XLinkPubRecImp.matrix." + name.toUpperCase() + "     = -1;")
    }
    if ((name.toUpperCase() == "TERMS") && (val != ""))
    {   val = val + UrlApiPubRecImp.getPRMAField("True", "BooleanMode");
	    UrlApiPubRecImp.matrix.BooleanMode     = -1;
    }

    return val
}

/**
	quote (") 	&quot;
	apostrophe (') 	&apos;
	ampersand (&) 	&amp;
	less than (<) 	&lt;
	greater than (>) 	&gt;
 */
XLinkPubRecImp.getField = function(value, type, formId)
{
	if (formId === null) 
	{
		formId = type;
	}

	value = value.replace(/[^a-zA-Z0-9*!_:/()\-]/g, " ");
	
	return '<field type="' + type + '" formId="' + formId + '">' + value + '</field>';

};

XLinkPubRecImp.getPRMAField = function(value, name)
{
    if (name != "DOB" && name != "LoanAmountOperator" && name != "TaxAmountOperator" && name != "LandValueOperator" && name != "SalePriceOperator")
	    value = value.replace(/[^a-zA-Z0-9*!_:/()\-]/g, " ");
	
	return '<field name="' + name + '">' + value + '</field>';

};

XLinkPubRecImp.useGet = function(chunnel)
{
	if (Truth.isTrue(chunnel.pwd) && Truth.isTrue(chunnel.uid)) 
	{
		return false;
	}
	if (Truth.isTrue(chunnel.getSearch()))
	{
		return false;
	}
	return true;
}/**
 * MasterQuery Implementor for Instant Activation.
 * @constructor
 * @private
 */
function IaLndbImp()
{
	throw new Error("IaLndbImp is a static class. Do not instantiate.");
}

IaLndbImp.DEFAULT_DOMAIN = "www4.lexisnexis.com";
IaLndbImp.DEFAULT_VERB   = "activate.do";

// Create API Matrix
// The matrix is used to cast object elements into those used by the API.
IaLndbImp.matrix          = new Object();

// Filter out MQ fields that we don't want in the query string
IaLndbImp.matrix.protocol = -1;
IaLndbImp.matrix.verb     = -1;
IaLndbImp.matrix.api      = -1;
IaLndbImp.matrix.target   = -1;
IaLndbImp.matrix.method   = -1;
IaLndbImp.matrix.source   = -1;
IaLndbImp.matrix.search   = -1;
IaLndbImp.matrix.originationcode = -1;
IaLndbImp.matrix.TOCTarget     = -1;	

IaLndbImp.matrix.uid             = "userId";
IaLndbImp.matrix.pwd             = "password";	
IaLndbImp.matrix.mod_id          = "modelId";
IaLndbImp.matrix.mod_psw         = "modelPassword";
IaLndbImp.matrix.fname           = "firstName";
IaLndbImp.matrix.lname           = "lastName";
IaLndbImp.matrix.cookie          = "longLiving";
IaLndbImp.matrix.org_id          = "orgId";
IaLndbImp.matrix._url            = "url";
	
/**
 * Takes a chunnel object and submits it. The last step in the journey
 * of a chunnel object before it becomes a LN search result.
 */
IaLndbImp.submit = function(chunnel)
{
	// Preprocessor needs to convert generic after field 
	// to XLink's relativedate field
	IaLndbImp._preprocessor(chunnel);

	var linker = IaLndbImp.getLink(chunnel);

	// If no target, set the target for the same window.	
	if (!Truth.isTrue(chunnel.target))
	{
		chunnel.target = "_self";
	}
	
	prompt("", linker);
	
	// var w = window.open(linker, chunnel.target, NEW_WINDOW_FEATURES); 

	// chunnel = null;
};

/**
 * Take any actions that need to be made on the MQ object before it gets
 * submitted to its specific API.
 */
IaLndbImp._preprocessor =  function(chunnel)
{
	chunnel.protocol = "https:";

	return chunnel;
};

/**
 * Returns the link that is the target for the API call.
 * This can be used as the action for a form or as the location
 * for a called to window.open.
 *
 * The query string is return based upon the chunnel values filtered 
 * through the implementor's matrix
 */
IaLndbImp.getLink = function(chunnel)
{
	var action;
	
	var verb = chunnel.get("verb");
	
	if (!Truth.isTrue(chunnel.get("verb")))
	{
		var verb = IaLndbImp.DEFAULT_VERB;
	}
	
	if (Truth.isTrue(chunnel.override))
	{
		action = chunnel.override;
	}
	else
	{
		action = chunnel.protocol + "//" + IaLndbImp.DEFAULT_DOMAIN + "/urlapi/" + verb;
	}

	return action + "?" + SearchImplementor.getQueryStringCaseInsensative(chunnel, IaLndbImp.matrix);

};