/** **********************************************************************
 *
 * SevenvalFITV3.js (C) Sevenval AG 1999-2006
 *
 * Javascript rewriting functions for SevenvalFIT 
 * see http://www.sevenval.com for more information
 * this code was written by a sound on bell :-)
 *
 * you are not allowed to modify, distribute or use this code without
 * permission of Sevenval AG
 *
 */

/** **********************************************************************
 * globals
 */
var fitEngine          = 'sevenval.fit';
var fitSeparator       = '/7val-';
var fitUrlKey          = "url";
var fitUrlSeparator    = fitSeparator+'fit-';
var fitQMEncoder       = '7val-fit-query';
var fitCommonUrlSep    = fitUrlSeparator+fitUrlKey;
var fitKeyValSeparator = "=";
var fitRewriteText     = 1;
var fitWhiteSpace      = " \t\r\n";
var fitUrlIgnore       = "/$SEVENVAL$/";
var fitDecodeCache     = new Array();
var fit_confirmOn = true;
/** **********************************************************************
 * error handling
 */

//window.onerror = FitErrorHandler;

function FitErrorHandler(msg, url, line)
{
	if (sv_debugMode) {
		alert("JavaScript Error: '" + msg + "'\n at " + url + " in line " + line);
	}

	/* return false to enable Browser Error message */
	return false;
}

function FitDebugContinue(msg) 
{
	if (sv_debugMode == true) {
		return confirm("FIT-DebugMode Message:\n" + msg);
	}

	return true;
}

function FIT_confirm(msg) 
{
	if (fit_confirmOn) {
		fit_confirmOn = confirm(msg);
	}
}

/** **********************************************************************
 * cookie handling
 */

function fit_trim(s) 
{
	while ((s.substring(0,1) == ' ') || (s.substring(0,1) == '\n') || (s.substring(0,1) == '\r')) {
		s = s.substring(1,s.length);
	}
	
	while ((s.substring(s.length-1,s.length) == ' ') || (s.substring(s.length-1,s.length) == '\n') || (s.substring(s.length-1,s.length) == '\r')){
		s = s.substring(0,s.length-1);
	}

	return s;
}

function FIT_Cookie(str)
{
	this.cookie_string = fit_trim(str);
	this.path = "/";
	this.domain = "";
	this.name = "";
	this.ok = false;
	args = str.split(';');
	for (var i = 0; i < args.length; i++) {
		if (args[i] != '') {

		   var key = fit_trim(args[i].substr(0, args[i].indexOf("=")));
		   var val = fit_trim(args[i].substr(args[i].indexOf("=") + 1, args[i].length));

			if (key == "") {
				continue;
			}

			if (key.length) {
				switch (key.toLowerCase()) {
				case "path":
					this.path = val;
					break;
				case "domain":
					this.domain = val;
					break;
				case "expires":
					this.expires = val;
					break;
				default:
					if (str.indexOf(key) == 0) {
						this.name = key;
						this.value = val;
					}
				}
			}
		}
	}
	
	if (this.name.length) {
		this.ok = true;
	}
}


function FIT_cookie_encode(str)
{
    str = escape(str);
    str = escape(str);
    return str;
}


function FIT_cookie_decode(str)
{
    str = unescape(str);
    str = unescape(str);
    return str;
}

function FIT_parseCookie(dc)
{
    c = dc.split(/\w{32}=/);
    cookies = new Array();
	
    var i = 0;
    var j = 0;
	
    while (i < c.length) {
		if (c[i] != "") {
			cookie = new FIT_Cookie(FIT_cookie_decode(c[i]));
			if (cookie.ok){
				cookies[j] = cookie;
				j++;
			}
		}
		i++; 
    }
    return cookies;
}


// This parses Fit cookies into an array
fit_cookies = FIT_parseCookie(document.cookie);

function FIT_getCookiesForTarget(target)
{
	var res = new Array();
	testurl = new FitUrlParser(sv_base_url[target]);
	
	var keys = new Array();
	for (var i = fit_cookies.length - 1; i >=0; i--) {
		var cookie = fit_cookies[i];
		if (keys[cookie.name]) {
			continue;
		}
		keys[cookie.name] = 1;
		if (testurl.domain.lastIndexOf(cookie.domain) - (testurl.domain.length - cookie.domain.length) != 0) {
			continue;
		}
		if (testurl.pathname.indexOf(cookie.path) != 0) {
			continue;
		}
		res[res.length] = cookie;
	}

	return res;
}

function FIT_getCookieStringForTarget(target)
{
	var res = "";
	var cookies = FIT_getCookiesForTarget(target); 
	for (var i=0; i < cookies.length; i++) {
		cs = cookies[i].cookie_string;
		res += cookies[i].name + "=" + cookies[i].value + ";";
	}
	//FIT_confirm("CookieString: " + res);
	return res;
}

/**
 * FitParseCookie(string, target)
 * 
 * string: the cookie string set by the js
 * target: the url-target
 *
 */

function FitParseCookie(string, target)
{
	if (typeof(sv_CookieJar[target]) != "object") {
		sv_CookieJar[target] = new Array();
	}
	var arr = new Array();
	arr = string.split("; ");
	for (var i = 0; i< arr.length; i++) {
		if (arr[i].indexOf("expires") == 0) continue;
		if (arr[i].indexOf("path") == 0) continue;
		if (arr[i].indexOf("domain") == 0) continue;
		if (arr[i].indexOf("secure") == 0) continue;
		var cookie = new Array();
		cookie = arr[i].split('=');
		var found = false;
		for (var j = 0; j < sv_CookieJar[target].length; j++) {
			if (sv_CookieJar[target][j].indexOf(cookie[0]) == 0) {
				sv_CookieJar[target][j] = arr[i];
				found = true;
				break;
			}
		}
		if (!found) {
			// MSIE doesnt know much about push
			var jarlength = sv_CookieJar[target].length;
			sv_CookieJar[target][jarlength] = arr[i];
		}
	}
}


/**
 * FitMakeCookieString(target)
 * 
 * target: the url-target
 *
 */

function FitMakeCookieString(target)
{
	if (typeof(sv_CookieJar[target])!="object") {
		return "";
	}
	
	if (typeof(target)!= "string") {
		return "";
	}

	return "" + sv_CookieJar[target].join("; ") + "";
}


/**
 * FitReadCookie(string, context, target)
 * 
 * string: the get cookie string for js
 * context: the context command 
 * target: the url-target
 *
 */

function FitReadCookie(string, context, target)
{
	if (!target) {
		target = fitUrlKey +"1";
	}
	
	if (fit_cookies.length) {
		return FIT_getCookieStringForTarget(target);
	}

	return "" + FitMakeCookieString(target) + "";
}


/**
 * FitSetCookie(string, context, target)
 * 
 * string: the get cookie string for js
 * context: the context command 
 * target: the url-target
 *
 */

function FitSetCookie(string, context, target)
{
	if (typeof(string) != "string") {
		return string;
	}

	retval = "dummy=; path=/; expires=Wed, 24-Sep-2003 10:00:00";

	var buf = string + "";

	c = new FIT_Cookie(buf);
	fit_cookies[fit_cookies.length] = c;

	if (sv_initPhase && fit_cookies) {
		return retval;
	}
	
	if (buf.indexOf("domain") == -1) {
		buf += "; domain=" + sv_plain_host[target];
	}
	if (!target) {
		target = fitUrlKey +"1";
	}
	
	if (sv_initPhase) {
		return retval;
	}
	
	if (sv_sid == '0') {
		return;
	}
	
	buf = escape(buf);
	var dummy = new Image();
	dummy.src = "/setCookie.fit"+fitUrlSeparator+"sid=" + sv_sid + fitUrlSeparator + "cookie=" + buf;

	return retval;
}


/******************************************************************************************************************************************************/
/*                                                                                                                                            CUT-NEW */
/******************************************************************************************************************************************************/


/** **********************************************************************
 * new Link-Decoding
 */

function FitDecodeBase(ctxt,trgt) 
{
	var c = sv_full_url[trgt];
	
	if (ctxt) {
		if(ctxt.sv_location) {
			c = ctxt.sv_full_url[trgt];
		} else if(ctxt.location && 
			  ctxt.location.href && 
			  ctxt.location.href != 'about:blank') {
			c = ctxt.location.href;
		}
		else if (ctxt.href && !ctxt.src) { // MSIE sets both properties for images
			c = ctxt.href;
		} else if (ctxt.URL) {
			c = ctxt.URL;
		}
	}
	
	var r = FitGetParam(c, fitUrlSeparator + trgt);
	
	return (r == "") ? c : r;
}

function FitDecodeBaseObj(ctxt,trgt) 
{
	if (ctxt && ctxt.sv_is_ssl) {
		return ctxt;
	} else {
		return self;
	}
}

function FitDecodeBasePrefix(ctxt, trgt) 
{
	var r = "";
	
	if (ctxt.sv_location) {
		r = ctxt.sv_prefix[trgt];
	}
	
	if (r == "") {
		r=sv_prefix[trgt];
	}

	return r;
}

function FitDecodeObjOnly(obj,trgt) 
{
	if (typeof(obj) != "string") {
		return obj;
	}
	
	var ret = FitGetParam(obj, fitUrlSeparator + trgt);
	
	if (ret == "") {
		ret = obj;
	}
	
	return ret;
}

function FitDecodeReferrer(obj, ctxt, trgt)
{
	if (trgt == "template") {
		return FitDecodeHref(obj, ctxt, trgt);
	} else {
		return FitDecodeObjOnly(obj, trgt);
	}
}

function FitDecodeHref(obj, ctxt, trgt) 
{
	var ret = FitDecodeBase(ctxt,trgt);

	if (ret == "") {
		ret = FitGetParam(obj, fitUrlSeparator + trgt);
	}
	// alert('FitDecodeHref('+obj+', '+ctxt+', '+trgt+')'+"\n"+ret);

	if (fitDecodeCache[ret]) {
		return fitDecodeCache[ret];
	}
	
	return ret;
}

function FitDecodeUrl(obj, ctxt, trgt) 
{
	return FitDecodeHref(obj, ctxt, trgt);
}

function FitDecodeSrc(obj, ctxt, trgt)
{
	return FitDecodeObjOnly(obj, trgt);
}

function FitDecodeAction(obj, ctxt, trgt)
{ 
	return FitDecodeObjOnly(obj,trgt);
}

function FitDecodeProtocol(obj, ctxt, trgt)
{ 
	if (!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	
	return purl.protocol;
}

function FitDecodeHost(obj, ctxt, trgt)
{
	if (!ctxt.sv_location) {
		return obj;
	}

	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	
	return purl.host;
}

function FitDecodeDomain(obj, ctxt, trgt)
{
	if (!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	
	return purl.domain;
}

function FitDecodeHostname(obj, ctxt, trgt)
{
	if (!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	
	return purl.hostname;
}

function FitDecodePort(obj, ctxt, trgt)
{
	if (!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	
	return purl.port;
}

function FitDecodePathname(obj, ctxt, trgt)
{
	if (!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	
	return purl.pathname;
}

function FitDecodeSearch(obj, ctxt, trgt)
{
	if (!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	
	return purl.search;
}

/** **********************************************************************
 * new Link-Encoding
 */

function FitEncodeWithBase(base,url) 
{
	var ret = "";
	if (url.length == 0) {
		ret = base;
	} else if (FitCheckNetAbs(url)) {
		ret = url;
	} else {
		var burl = new FitUrlParser(base);
		if (url.charAt(0) == '/') {
			burl.pathname = url;
			burl.search = burl.hash = "";
			ret = FitConstructUrl(burl);
		}
	    else if (url.charAt(0) == '?') {
			burl.search = url;
			burl.hash = "";
			ret = FitConstructUrl(burl);
		}
		else if (url.charAt(0) == '#') {
			ret = url;
		}
		else {
			burl.pathname = burl.directory + ((burl.directory.charAt(burl.directory.length - 1) == '/') ? '' : '/') + url;
			burl.search = burl.hash = "";
			ret = FitConstructUrl(burl);
		}
	}
	//alert('FitEncodeWithBase('+base+', '+url+')'+"\n"+ret);	
	return ret;
}

function FitGetMediaBase(ctxt) 
{
	var ctxt = FitDecodeBaseObj(ctxt);

	if (ctxt.sv_is_ssl) {
		return '/sslproxy.fit/';
	} else {
		return '';
	}
}

function FitCheckNetAbs(obj) 
{
	return (obj.toLowerCase().indexOf('http:') == 0 || 
		obj.toLowerCase().indexOf('https:') == 0 ||
		obj.toLowerCase().indexOf('file:') == 0 ||
		obj.toLowerCase().indexOf('mms:') == 0 ||
		obj.toLowerCase().indexOf('mailto:') == 0);
}

function FitCheckWrongProto(obj) 
{
	return (obj.toLowerCase().indexOf('file:') == 0 ||
		obj.toLowerCase().indexOf('mailto:') == 0 ||
		obj.toLowerCase().indexOf('mms:') == 0);
}

function FitEncodeMedia(obj, ctxt, trgt) 
{
	if (typeof(obj) != "string") {
		return obj;
	}
	
	if (FitCheckWrongProto(obj)) {
		return obj;
	}
	
	var base = FitDecodeBase(ctxt, trgt);
	var nurl = FitEncodeWithBase(base, obj);
	var ret = nurl.indexOf('/sslproxy.fit/') != -1 ? nurl : FitGetMediaBase(ctxt) + nurl; 

	//alert('FitEncodeMedia('+obj+', '+ctxt+', '+trgt+')'+"\n"+ret);
	return ret;
}

function FitEncodeHref(obj, ctxt, trgt) 
{
	if (typeof(obj) != "string"
		|| FitCheckWrongProto(obj)
		|| obj.indexOf(sv_server_http) == 0 
		|| obj.indexOf(sv_server_https) == 0
		|| (obj.indexOf('/') == 0
			&& obj.match(/^\/[a-zA-Z0-9_]+\.fit/))) {
		return obj;
	}

	// Check for local anchor
	if (obj.charAt(0)=='#') {
		return obj;
	}

	if (obj.toLowerCase().indexOf('javascript') == 0) {
		ret = FitRewriteString(obj, ctxt, trgt);
	}
	else {
		var nurl = FitEncodeWithBase(FitDecodeBase(ctxt, trgt), obj);
		fitDecodeCache[nurl] = obj;
		var baseobj = FitDecodeBaseObj(ctxt);
		if (trgt == "template"
			&& baseobj.sv_location
			&& baseobj.sv_templateRedir) {
			var newurl = FitEncodeTemplateParam(baseobj.sv_location, nurl);
			var msg = "The Template wants to redirect to:\n";
			msg += nurl + "\ndefault is to redirect to:\n";
			msg += newurl + "\nOverwrite this with sv_templateRedir=false\nContinue?";
			if (FitDebugContinue(msg)) {
				return newurl;
			}
			return '#';
		}
		var ret = FitDecodeBasePrefix(ctxt, trgt) + nurl;
	}

	//alert('FitEncodeHref('+obj+', '+ctxt+', '+trgt+')='+ret);
	return ret;
}

function FitEncodeLocation(obj, ctxt, trgt) 
{
	return FitEncodeHref(obj, ctxt, trgt);
}

function FitEncodeReplace(obj, ctxt, trgt) 
{
	return FitEncodeHref(obj.href, ctxt, trgt);
}

function FitEncodeSrc(obj, ctxt, trgt) 
{
	if (FitGuessUrlContext(obj + "") == 'imgsrc') {
		return FitEncodeMedia(obj, ctxt, trgt);
	} else if(ctxt && (ctxt.window || ctxt.location || ctxt.scrolling)) {
		return FitEncodeHref(obj, ctxt, trgt);
	} else {
		return FitEncodeMedia(obj, ctxt, trgt);
	}
}

function FitEncodeUrl(obj, ctxt, trgt) 
{
	return FitEncodeHref(obj, ctxt, trgt);
}

function FitEncodeAction(obj, ctxt, trgt) 
{
	return FitEncodeHref(obj, ctxt, trgt);
}

/* we replace parts and update the whole */

function FitEncodeHost(obj, ctxt, trgt) 
{  
	if (!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt,trgt));
	purl.host = obj;
	
	return FitEncodeHref(FitConstructUrl(purl), ctxt, trgt);
}

function FitEncodeHostname(obj, ctxt, trgt) 
{
	if (!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	purl.hostname = obj;
	
	return FitEncodeHref(FitConstructUrl(purl), ctxt, trgt);
}

function FitEncodePathname(obj, ctxt, trgt) 
{
	if (!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	purl.pathname = obj;
	
	return FitEncodeHref(FitConstructUrl(purl),ctxt,trgt);
}

function FitEncodeSearch(obj, ctxt, trgt) 
{
	if (!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	purl.search = obj;
	
	return FitEncodeHref(FitConstructUrl(purl), ctxt, trgt);
}

function FitEncodePort(obj, ctxt, trgt) 
{
	if (!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	purl.port = obj;
	
	return FitEncodeHref(FitConstructUrl(purl), ctxt, trgt);
}

function FitEncodeProtocol(obj, ctxt, trgt) 
{
	if(!ctxt.sv_location) {
		return obj;
	}
	
	var purl = new FitUrlParser(FitDecodeBase(ctxt, trgt));
	purl.protocol = obj;
	
	return FitEncodeHref(FitConstructUrl(purl), ctxt, trgt);
}

function FitConstructUrl(ourl) 
{
	return ourl.protocol + '//' + ourl.host + ourl.pathname + ourl.search + ourl.hash;
}

function FitEncodeTemplateParam(fullurl, newtemplate) 
{
	var param = FitCheckTemplateParam(fullurl);
	var newurl = '';

	if (param == '') {
		var pos = fullurl.indexOf(fitCommonUrlSep);
		newurl = fullurl.substring(0, pos) + fitUrlSeparator + 'template1=' + newtemplate + fullurl.substr(pos);
	}
	else {
		var pos = fullurl.indexOf(param);
		var origtemplate = FitGetParam(fullurl,param);
		var len = origtemplate.length;
		newurl = fullurl.substring(0, pos) + param + '=' + newtemplate + fullurl.substr(pos + len);			
	}
	
	return newurl;
}

/** **********************************************************************
 * new Document Write handling
 */

function FitWrite(str, real_context, target) 
{
	//alert('FitWrite('+str+', '+real_context+', '+target+')');
	if ((real_context.open && real_context.document) || (real_context.write && real_context.writeln)) {
		str = str + '';
		var test = (str.lastIndexOf('<') < str.lastIndexOf('>'));
		var ret = '';
		if (test && !sv_write_cache.length) {
			FitDoWrite(str, real_context, target);
		} else {
			FitAddToWriteBuffer(str, real_context, target);
			if (test) {
				FitFlushWriteBuffers(target);
			}
		}
		return true;
	}
	return false;
}

function FitAddToWriteBuffer(str, real_context, target) 
{
	//alert('FitAddToWriteBuffer('+str+', '+real_context+', '+target+')');

	if (sv_write_cache.length > 0) {
		var i;
		for (i = 0; i < sv_write_cache.length; i++) {
			if (sv_write_cache[i].length == 3) {
				if (sv_write_cache[i][2] == target) {
					if ((real_context && sv_write_cache[i][1] && sv_write_cache[i][1]==real_context) || (!real_context && !sv_write_cache[i][1])) {
						sv_write_cache[i][0] += str;
						return;
					}
				}
			}
		}
	}

	sv_write_cache[sv_write_cache.length] = new Array(str, real_context, target);
}


function FitDoWrite(str, real_context, target) 
{
	// alert('FitDoWrite('+str+', '+real_context+', '+target+')');
	
	var doctarget = self.document;
	
	if (real_context) {
		if (real_context.window && real_context.document) {
			doctarget = real_context.document;
		} else {
			doctarget = real_context;
		}
	}
	
	var result = FitParseHTML(str,'document.write',target);
	// alert('writing:'+result);
	doctarget.write(result);
	//alert('writing ended:'+result);
}

function FitFlushWriteBuffers(target) 
{
	//alert('FitFlushWriteBuffers');
	var i;
	for (i = 0; i < sv_write_cache.length; i++) {
		if (sv_write_cache[i][2] == target) {
			if (sv_write_cache[i][0].length) {
				FitDoWrite(sv_write_cache[i][0], sv_write_cache[i][1], sv_write_cache[i][2]);
			}
			sv_write_cache[i] = new Array();;
		}
	}

	return true;
}

/** **********************************************************************
 * new Funccall Handling
 */

function FitEval(obj, ctxt, trgt) 
{
	var ret = FitRewriteString(obj, ctxt, trgt);		
	// alert('FitEval('+obj+', '+ctxt+', '+trgt+') returns '+ret);
	return ret; 
}

function FitRewriteString(str, ctxt, trgt)
{
	if (typeof(str) != "string") {
		return str;
	}
	
	if (str.indexOf('/') == -1 && str.indexOf('http') == -1) {
		return str;
	}

	var pchar = '';
	var cchar = '';
	var ret = '';
	var i = 0;
	var ostrLen = str.length;

	while (i < ostrLen) {
		cchar = str.charAt(i);
				
		if (cchar=="'" && pchar != "\\") {
			endStrPos = FitScanForChar(str.substr(i+1), "'");
			if (endStrPos != -1) {
				newStr = FitGuessEncodeStr(str.substring(i + 1, i + 1 + endStrPos), ctxt, trgt);
				if (newStr != "") {
					ret += "'"+newStr;
					i += endStrPos+1;
				}
			}
		}
		else if (cchar=='"' && pchar != "\\") {
			endStrPos = FitScanForChar(str.substr(i+1), '"');
			if (endStrPos != -1) {
				newStr = FitGuessEncodeStr(str.substring(i + 1, i + 1 + endStrPos), ctxt, trgt);
				if (newStr != "") {
					ret += '"' + newStr;
					i += endStrPos+1;
				}
			}
		}
		ret += cchar;
		pchar = cchar;
		i++;
	}
		
	return ret;
}

function FitGuessEncodeStr(string, context, trgt) 
{
	if (FitCheckUrlString(string)) {
		context = FitGuessUrlContext(string);
		return FitEncodeHref(string, context, trgt);
	}
	
	return "";
}
/******************************************************************************************************************************************************/
/*                                                                                                                                            CUT-NEW */
/******************************************************************************************************************************************************/




/** **********************************************************************
 * url handling
 */

/**
 * FitDecodeLink(str, context, target)
 *
 * decode information regarding js-rvalues
 *
 * str: string based on context
 * context: The caller context
 * target: the target to get 
 */

function FitGetBase(baseref, target, what) 
{
	if (baseref == "" || baseref == 'document') {
		baseref='self';
	}
	
	var mbase = '';
	
	if (target == 'template') {
		mbase = eval(baseref + ".sv_full_url['template']");
	} else {
		mbase = eval(baseref + "." + what);
	}
	
	if (!mbase) {
		mbase = eval(baseref + ".location");
	}
	mbase += "";

	var r = FitGetParam(mbase, fitUrlSeparator + target);
	if (r == "") {
		r = mbase;
	}
	
	return FITRemoveReferrer(r);
}

function FitIsLocation(ident) 
{
	return (ident == 'href' || 
		ident == 'location' || 	
		ident == 'host' ||
		ident == 'port' ||
		ident == 'hostname' ||
		ident == 'pathname' ||
		ident == 'hash' ||
		ident == 'protocol' ||
		ident == 'search');
}

function FitDecodeLink(str, context, target)
{
	if (!context) {
		return str;
	}
	
	if (!FITLeftTruncMatch(context,'location')) {
		if (typeof(str) != "string") {
			return str;
		}
	}
	
	if (!target) {
		return str;
	}
	
	str += "";
	str = FITRemoveReferrer(str); 
	var r = "";
	//alert('FitDecodeLink('+str+', '+context+', '+target+')');
	context = context.toLowerCase();
	context = FitStrreplace(context, "document.url", 'location.href');
	var ident = FitGetIdent(context);
	var identPrefix = FitGetIdentPrefix(context);
	var baseref = identPrefix;
	var base = "";

	if (ident == 'referrer') {
		baseref = FitGetIdentPrefix(identPrefix);
		r = FitGetBase(baseref,target,"document.referrer");
		if (r == "") {
			r = str;
		}
	}
	else if (FitIsLocation(ident) && identPrefix.indexOf('this') != 0) {
		if (ident != 'location') {
			baseref = FitGetIdentPrefix(identPrefix);
		}

		base = FitGetBase(baseref, target, "sv_location");
 
		// here we have a base
		purl = new FitUrlParser(base);

		if (ident == "search") {
			r = purl.search;
		} else if (ident == "host") {
			r = purl.host; 
		} else if (ident == "hash") {
			r = purl.hash; 
		} else if (ident == "hostname") {
			r = purl.hostname; 
		} else if (ident == "port") {
			r = purl.port; 
		} else if (ident == "protocol") {
			r = purl.protocol; 
		} else if (ident == "pathname") {
			r = purl.pathname; 
		} else {
			r = purl.href;
		}
		
		if (r == '') {
			r = base;
		}
	}
	else {
		base = FitGetParam(str, fitUrlSeparator + target);
		if (base == '') {
			r = str;
		} else {
			r = base;
		}
	}
	
	//alert('FitDecodeLink('+str+', '+context+', '+target+')='+r);
	return r;
}


/**
 * FitEncodeLink(str, context, target)
 *
 * encode information regarding js-lvalues
 *
 * str: The Url
 * context: The caller context
 * target: the target to get 
 */

function FitEncodeLink(str, context, target)
{
	if (typeof(str) != "string") {
		return str;
	}
	
	if (!target) {
		target = fitUrlKey +"1";
	}
	
	var doRewrite = true;
	var url = str + "";
	var result;
	//alert('FitEncodeLink('+str+', '+context+', '+target+')');

	var targetframe = self;

	if (url=="") {
		return "";
	}

	if (FitCheckWrongProto(str)) {
		return str;
	}

	// Do not process FIT Urls;
	if (url == self.location.href || 
		url == self.location.path || 
		url.indexOf(sv_server_http) == 0 ||
		url.indexOf(sv_server_https) == 0) {
		return url;
	}
	
	if (url.indexOf('/sslproxy.fit') == 0) {
		return url;
	}
	
	var	ident = FitGetIdent(context);
	var identPrefix = FitGetIdentPrefix(context);

	if (ident == 'open' && identPrefix.indexOf('document') != -1) {
		return str;
	}

	url = fit_trim(url);

	var lcurl = url.toLowerCase();
	if (lcurl.indexOf("javascript:") == 0) {
		result = "javascript:" + FitRewriteStrings(url.substr(11, url.length - 11), "href", target);
		return result;
	}
	
	url = FitRemoveSpace(url);
	if (lcurl.indexOf("#") == 0) {
		return str;
	}

	var baseUrl = sv_base_url[target];
	var fullUrl = sv_full_url[target];
	var baseHost = sv_base_host[target];
	var preFix = sv_prefix[target];
	var tframe = self;
	if (context.indexOf(".") != 0 && context.indexOf(".location") != -1) {
		targetframe = context.substring(0, context.indexOf(".location"));
		tframe = eval(targetframe);
		if (tframe.sv_base_url) {
			baseUrl = tframe.sv_base_url[target];
			fullUrl = tframe.sv_full_url[target];
			baseHost = tframe.sv_base_host[target];
			preFix = tframe.sv_prefix[target];
		}
	}

	if (lcurl.indexOf("http") == 0) {
	}
	else if (url.indexOf("/") == 0) {
		url = baseHost + url;
	}
	else if (url.indexOf("?") == 0) {
		var furl = fullUrl;
		if (fullUrl.lastIndexOf('?') != -1) {
			furl = fullUrl.substring(0, fullUrl.lastIndexOf('?'));
		}
		url = furl + url;
	} else {
		if (baseUrl.lastIndexOf("/") == baseUrl.length - 1) {
			url = baseUrl + url;
		} else {
			url = baseUrl + '/' + url;
		}
	}

	// at this Point we have an absolute non-FIT Url
	if (context == 'svparser.flash') {
		if (url.indexOf('?') != -1) {
			url += '&';
		} else {
			url += '?';
		}
		
		return '/flashproxy.fit/'+url+'svbaseurl='+baseUrl+'&svprefix='+preFix;
	}

	if (sv_cid != 0 && context == "linkrelstyle") {
		return "/cssproxy.fit" + fitUrlSeparator + "cfgpfm=" + sv_cfg_pf_modtime + fitUrlSeparator+ "cid=" + sv_cid + fitUrlSeparator + target + "=" + url;
	}

	if (context == "scriptsrc") {
		if (sv_cid != 0) {
			return "/jsproxy.fit" + fitUrlSeparator + "cfgpfm=" + sv_cfg_pf_modtime + fitUrlSeparator + "cid=" + sv_cid + fitUrlSeparator + target + "=" + url;
		} else {
			url += fitUrlSeparator + 'mimetype=' + target + '-' + 'js';
		}
	}

	if (target == 'template' && context.indexOf('location') != -1) {
		if (sv_templateRedir && tframe == self && FitGetParam(self.sv_location, fitCommonUrlSep) != '') {
			// a template wants to redirect within a cooperation
			var fullurl = self.sv_location;
			var param = FitCheckTemplateParam(fullurl);
			var newurl = '';
			if (param == '') {
				var pos = fullurl.indexOf(fitCommonUrlSep);
				newurl = fullurl.substring(0, pos) + fitUrlSeparator + 'template1=' + url + fullurl.substr(pos);
			} else {
				var pos = fullurl.indexOf(param);
				var origtemplate = FitGetParam(fullurl,param);
				var len = origtemplate.length;
				newurl = fullurl.substring(0, pos) + param + '=' + url + fullurl.substr(pos + len);			
			}
			var msg = "The Template wants to redirect to:\n";
			msg += url+"\ndefault is to redirect to:\n";
			msg += newurl+"\nOverwrite this with sv_templateRedir=false\nContinue?";
			if (FitDebugContinue(msg)) {
				return newurl;
			}
			return '#';
		} else {
			return url;
		}
	}
	
	if (identPrefix == 'svparser.original' && target == 'template') {
		return url;
	}

	if (FitCheckStringSuffixes(str, "png|gif|jpeg|jpg|class|swf")) {
		context = "imgsrc";
	}

	if (!sv_is_ssl) {
		if (context == "imgsrc" || context == 'svparser.img') {
			return url;
		}
	} else {
		if (context == "imgsrc" || context == 'svparser.img') {
			preFix = '/sslproxy.fit/';
		}
	}

	result = preFix + url;

	if (ident == "pathname") {
		return result;
	}

	lcurl = url.toLowerCase();
	result = this.location.protocol + '//' + this.location.host + result;
	result = FitEncodeQuery(result);
	
	//alert('FitEncodeLink('+str+', '+context+', '+target+')=('+baseUrl+')'+result);
	return result;
}


function FitGuessUrlContext(string) 
{
	if (FitCheckStringSuffixes(string, "png|gif|jpeg|jpg|class|swf")) {
		return 'imgsrc';
	} else {
		return 'href';
	}
}

function FitCheckUrlString(string) 
{
	string = string.toLowerCase();

	if (string.indexOf('\n') == -1 && string.indexOf('\r') == -1 && string.indexOf(' ') == -1) {
		if (string.indexOf('/') == 0 || string.indexOf('http://') == 0 || string.indexOf('https://') == 0) {
			return true;
		}
		if (FitCheckStringSuffixes(string, "htm|html|php|class|png|gif|jpeg|jpg|class|swf")) {
			return true;
		}
	}

	return false;
}

function FitGuessEncodeString(string, context, target) 
{
	if (FitCheckUrlString(string)) {
		context = FitGuessUrlContext(string);
		return FitEncodeLink(string, context, target);
	}

	return "";
}

/** **********************************************************************
 * content handling (js/html)
 */

function FitRewriteStrings(str, context, target) 
{		
	if (!fitRewriteText || typeof(str) != "string") {
		return str;
	}

	if (str.indexOf('/') == -1 && str.indexOf('http') == -1) {
		return str;
	}

	var pchar = '';
	var cchar = '';
	var ret = '';
	var i = 0;
	var ostrLen = str.length;

	while (i < ostrLen) {
		cchar = str.charAt(i);
				
		if (cchar == "'" && pchar != "\\") {
			endStrPos = FitScanForChar(str.substr(i+1), "'");
			if (endStrPos != -1) {
				newStr = FitGuessEncodeString(str.substring(i + 1,i + 1 + endStrPos), context, target);
				if (newStr != "") {
					ret += "'" + newStr;
					i += endStrPos + 1;
				}
			}
		}
		else if (cchar=='"' && pchar != "\\") {
			endStrPos = FitScanForChar(str.substr(i+1), '"');
			if (endStrPos != -1) {
				newStr = FitGuessEncodeString(str.substring(i + 1,i + 1 + endStrPos), context, target);
				if (newStr != "") {
					ret += '"' + newStr;
					i += endStrPos + 1;
				}
			}
		}
		ret += cchar;
		pchar = cchar;
		i++;
	}
		
	return ret;
}

function FitParseHTML(str, context, target)
{
	//confirm('FitParseHTML('+str+', '+context+', '+target+')');

	if (sv_is_ssl && sv_agressiveRewrite[target]) {
		var tmpstr = str + "";
		if (tmpstr.indexOf(fitEngine) == -1) {
			str = FitStrreplace(str, "https:\/\/" , sv_prefix[target] + "https://");
		}
	}

	if (typeof(str) != "string") {
		return str;
	}

	if (context == "eval" || context=="setTimeout") {
		return FitRewriteStrings(str, context, target);
	}

	var ident = FitGetIdent(context);

	if (ident=="eval" || ident == "setTimeout") {
		return FitRewriteStrings(str, context, target);
	}

	if (!target) {
		target = fitUrlKey +"1";
	}

	var content ="";
	var chunk = "";
	var state = 0; 

    // states: 0 default
	//		  1 inside a tag
	//		  2 inside \"
	//		  4 inside \'
	//		  8 last was backslash
	//        16 html comment

	for (var i = 0; i < str.length; i++)
	{
		var ch = str.charAt(i);

		// Check tag context only if not inside a str
		if ((state & 6) == 0) { // Not inside a str (state 2, 4)
			if (state & 16) { // inside comment
				if (str.substr(i).indexOf("-->") == 0) {
					state ^= 16; // clear comment state
					content += '<!--'+FitRewriteStrings(chunk, "", target)+'-->';
					chunk="";
					i += 2;
					continue;
				}
			} else if (state & 1) {
				if (ch == '>') {
					state ^= 1; // Clear tag state
					content += FitParseHtmlTag(chunk, target)
					chunk = "";
					continue; // ignore this character
				}
				if (ch == '=') {
					state |= 32; // May enter string state
				} else if (state & 32 && fitWhiteSpace.indexOf(ch) == -1){
					state ^= 32; // clear May enter string state
				}
			} else if(ch == '<') {
			    state ^= 32; // clear May enter string state
				// Check for comment 		old		if(string.substr(i).indexOf("<!--") == 0)
				if(str.charAt(i + 1) == '!' && str.charAt(i + 2) == '-') {
					i+=3; // Skip start of comment
					state |= 16; // set comment state
				} else {
					state |= 1; // set tag state
				}
				content += FitRewriteStrings(chunk, "", target);
				chunk = "";
				state ^= 32; // clear May enter string state
				continue; // ignore this character
			} else {
				state |= 32; // May enter string state				
			}
			// Look for string start
			if (ch == '"' && (state & 32)) { // a " string starts
				state |= 2;
			} else if (ch == "'" && (state & 32) ) { // a ' string starts
				state |= 4;
			}
			// No escaping outside a string, so no need to check it
			// We may clear the flag here, but it should not be set if there are no bugs in our parser
		}

		// inside a string, just search for its end.
		else
		{
			if (state & 8) {
				state ^= 8;
			}
			else if ((state & 2) && ch == '"') {
				state ^= 2; // the " string ends
			}
			else if ((state & 4) && ch == "'") {
				state ^= 4; // the ' string ends
			}
			else if (ch == "\\") {
				state |= 8;
			}
		}
		chunk += ch;
	}
	if ((state & 1)) {
		chunk = "<" + chunk;
	}

	content += FitRewriteStrings(chunk, "", target);
	
	//confirm('returning: '+content);
	return content;
}


function FitParseHtmlTag(text, target)
{
	if (!target) {
		target = fitUrlKey + "1";
	}
	
	if (typeof(text) != "string") {
		return text;
	}

	// skip closing tags
	if (text.charAt(0) == '/') {
		return '<' + text + '>';
	}

	var retval = "";
	var tagname = "";
	var lastKey = "";
	var lastValue = "";
	var lastQuote = "";
	var linkIsStyle = false;
	var state = 0; 
	var cur = "";

    // states: 0 default
	//	  1 inside double quotes    	
	//	  2 inside single quotes    	
	//	  4 last was backslash      	
	//    8 unquoted value found  

	var pos = 0;
	var lastpos = 0;

	// Skip leading whitespace
	pos = FitSkipSpace(text, pos);
	
	// read the tagname
	lastpos = pos;
	pos = FitNextSpace(text, pos);
	tagname = text.substr(lastpos, pos).toLowerCase();
	retval = tagname;
	
	while (pos < text.length) {
		// Get args
		pos = FitSkipSpace(text, pos);

		lastpos = pos;

		pos = FitNextToken(text,pos);
		lastKey = text.slice(lastpos, pos);			
		pos = FitSkipSpace(text, pos);

		if (text.charAt(pos) != '=') {
			retval += ' ' + lastKey;
			pos = FitSkipTokens(text, pos);
			continue;
		}

		pos = FitSkipTokens(text, pos);
		//alert('lastkey'+lastkey);
		lastpos = pos;

		for (var i = pos; i < text.length; i++) {
			cur = text.charAt(i);
			if (state == 0) {
				if (cur == '"') {
					lastpos = i + 1;
					state = 1;
				} else if(cur == "'") {
					lastpos = i + 1;
					state = 2;
				} else if (fitWhiteSpace.indexOf(cur) != -1) {
					lastValue = text.slice(lastpos, i);
				} else {
					state = 8;
					lastpos = i;
				}
			} else if (state == 1) {
				if (cur == '"') {
					state ^= 1;
					lastValue = text.slice(lastpos,i);						
					lastQuote = '"';
				} else if(cur == "\\") {
					state |= 4;
				}
			} else if(state == 2) {
				if (cur == "'") {
					state ^= 2;
					lastValue= text.slice(lastpos,i);
					lastQuote = "'";
				} else if(cur == "\\") {
					state |= 4;
				}
			} else if(state & 4) {
				state ^= 4;
			} else if(state == 8) {
				if (cur == " ") {
					lastValue= text.slice(lastpos,i);
					state = 0;
				}
			}
			if (lastKey.length && lastValue.length) {
				break;
			}
		}
		
		//alert('lastvalue'+lastValue);
		if (lastKey.length) {
			lastKey = lastKey.toLowerCase();
			if (!lastValue.length) {
				lastValue = text.slice(lastpos, text.length);
			}
		}
		
		if (lastKey == "rel" && lastValue.toLowerCase() == "stylesheet") {
			linkIsStyle = true;
		}
		if (tagname == 'link' && lastKey == "href" && (linkIsStyle || FitCheckStringSuffixes(lastValue, ".css"))) {
			//lastValue = FitEncodeHref(lastValue,"linkrelstyle", target);
			lastValue = FitEncodeLink(lastValue,"linkrelstyle", target);
		}
		else if (tagname == "script" && lastKey == "src") {
			//lastValue = FitEncodeSrc(lastValue, "scriptsrc", target);
			lastValue = FitEncodeLink(lastValue, "scriptsrc", target);
		}
		else if (tagname == "param" && lastKey == "value" && lastValue.indexOf('.swf') != -1) {
			lastValue = FitEncodeLink(lastValue, "svparser.flash", target);
			// lastValue = FitEncodeSrc(lastValue, "svprefix.flash", target);
		}
		else if (tagname == "object" && lastKey == "data" && lastValue.indexOf('.swf') != -1) {
			lastValue = FitEncodeLink(lastValue, "svparser.flash", target);
			// lastValue = FitEncodeSrc(lastValue, "svprefix.flash", target);
		}

		else if ((lastKey == "href" || lastKey == "src" || lastKey == "action" || lastKey == "background")) {
			if (tagname == 'embed') {
				if (lastValue.indexOf('.swf') != -1) {
					encodetarget = 'svparser.flash';
				} else {
					encodetarget = 'svparser.img';
				}
			}
			else if(tagname == 'script' || 
				tagname == 'frame' || 
				tagname == 'iframe' || 
				tagname == 'link' || 
				tagname == 'layer') {
				encodetarget = 'svparser.parse.href';
			} else if (tagname == 'img' || (tagname == 'input' && lastKey == "src")) {
				encodetarget = 'svparser.img';
			} else {
				encodetarget = 'svparser.original.' + lastKey;
			}
			lastValue = FitEncodeLink(lastValue, encodetarget, target);
		} else if (lastKey.indexOf('on')==0 && fitRewriteText) {
			lastValue = FitRewriteStrings(lastValue, "href", target);
		}
		lastValue = FitReplaceAttribute(target, tagname, lastKey, lastValue);
		retval += " " + lastKey + '=' + lastQuote + lastValue + lastQuote;
		lastKey = "";
		lastValue = "";
		lastQuote = "";
		pos = i + 1;
	}
	
	var closeform = '';
	if (tagname == 'form') {
		if (sv_formPos != -1) {
			closeform = '</form>';
		}
		sv_posOffset[target]++;
		sv_jsIndex[++sv_formPos] = target + '-' + (sv_origPos[target] + sv_posOffset[target]);
	}
	
	return closeform + "<" + retval + ">";
}

function FitSkipSpace(text, pos)
{
	while (fitWhiteSpace.indexOf(text.charAt(pos)) != -1) {
		if (++pos > text.length) {
			break;
		}
	}
	
	return pos;
}

function FitNextSpace(text, pos)
{
	while (fitWhiteSpace.indexOf(text.charAt(pos)) == -1) {
		if (++pos > text.length) {
			break;
		}
	}
	
	return pos;
}

function FitNextToken(text, pos)
{
	for (var i = pos; i < text.length; i++) {
		if (text.charAt(i) == " " || text.charAt(i) == "=") {
			break;
		}
	}
	
	return i;
}

function FitSkipTokens(text, pos)
{
	for (var i = pos; i < text.length; i++) {
		var cur = text.charAt(i);
		if (cur != " " && cur != "=") {
			break;
		}
	}
	
	return i;
}

/** ***********************************************************************
 * Common Functions 
 *
 */

function FitStrreplace(str, srch, repl, all)
{
	str = str + "";
	srch = srch + "";
	repl = repl + "";
	
	while (str.indexOf(srch) != -1) {
		var part1 = str.substr(0, str.indexOf(srch)); 
		var part2 = str.substr(str.indexOf(srch) + srch.length);
		str =  part1 + repl + part2;
		if (!all) {
			break;
		}
	}
	
	return str;
}

function FitRemoveSpace(str)
{
	str = FitStrreplace(str, " ", '', true);
	str = FitStrreplace(str, "\t", '', true);
	str = FitStrreplace(str, "\n", '', true);
	str = FitStrreplace(str, "\r", '', true);
	
	return str;
}

/**
 *
 *  FitScanForChar(str,strChar)
 *
 * str: a string
 * strChar: the character to find (skipping escaped ones)
 *
 * returns: the position of strChar in the string
 */

function FitScanForChar(str, strChar) 
{
	var state = 0;
	var cchar = '';
	var i = 0;
	
	for (i = 0; i < str.length; i++) {
		cchar = str.charAt(i);
		if (state == 1) {
			if (cchar == "\\") {
				state=0;
			}
		} else if (state == 0) {
			if (strChar == cchar) {
				return i;
			}
			if (cchar == "\\") {
				state = 1;
			}
		}
	}
	
	return -1;
}

/**
 *
 * FitGetIdent(str) 
 *
 * str: the string containing the identifier (e.g. top.location.href -> href)
 * returns: the rightmost part of the identifier
 */

function FitGetIdent(str) 
{
	return str.substring(str.lastIndexOf(".") + 1).toLowerCase();
}

/**
 *
 * FitGetIdentPrefix(str) 
 *
 * str: the string containing the identifier (e.g. top.location.href -> top.location)
 * returns: the left part of the identifier
 */

function FitGetIdentPrefix(str) 
{
	return str.substr(0, str.lastIndexOf(".")).toLowerCase();
}

/**
 *
 * FitGetParam(str, param_sep) 
 *
 * str: the string containing a param
 * param_sep: the parameter start-seperator 
 *
 * returns: "" or string in case of match
 */

function FitGetParam(str, param_sep) 
{
	if (str) {
		var start = str.indexOf(param_sep);
		var result;
		if (start == -1) {
			return "";
		}
		
		var str2right = str.substr(start + param_sep.length + 1);
		var end = str2right.indexOf(fitUrlSeparator);
		var endt = str2right.indexOf('/' + fitQMEncoder);
		if (endt == end && endt != -1) {
			end = str2right.indexOf(fitCommonUrlSep);
		}	
		
		if (end != -1) {
			result = str2right.substring(0, end);
		} else {
			result = str2right;
		}
		
		var qmencpos = result.indexOf(fitQMEncoder);
		if (qmencpos != -1) {
			result = result.substr(0, qmencpos) + '?' + result.substring(qmencpos + fitQMEncoder.length);
		}
		
		return result;
	}
	
	return "";
}
  
/**
 *
 * FitCheckStringSuffixes(string, suffixes) {
 *
 * string: the String to check
 * suffixes: a pipe-seperated list of suffixes 
 *           e.g. "jpg|gif" 
 *
 * returns: true or false
 */

function FitCheckStringSuffixes(string, suffixes) 
{
	var suffixarray = new Array();
	
	suffixarray = suffixes.split("|");
	if (string == "") {
		return false;
	}
	
	var lastPos = string.lastIndexOf('.');
	if (lastPos != -1) {
		var testSuffix = string.substring(lastPos+1).toLowerCase();
		for (var i = 0; i < suffixarray.length; i++) {
			if (suffixarray[i] == testSuffix) {
				return true;
			}
		}
	}
	
	return false;
}


/**
 *
 * FitIsAlpha(character)
 *
 * character: the character to check
 *
 * returns: true or false
 */

function FitIsAlpha(character) 
{
	var isalpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz0123456789";
	
	if (isalpha.indexOf(character) != -1) {
		return true;
	}
	
	return false;
}

/**
 *
 * FitShift(array)
 *
 * array: the array to shift
 * Removes the first element from an array and returns that element
 * returns: first element
 */

function FitShift(arr)
{
	if (arr.length != 0) {
		var result = arr[0];
		var i = 0;
		for (i = 0; i < arr.length-1; i++) {
			arr[i] = arr[i+1];
		}
		arr.length = arr.length-1;
		
		return result;
	}
	
	return;
}

/**
 *
 * FitPop(array)
 *
 * array: the array to pop
 * Removes the last element from an array and returns that element
 * returns: last element
 */

function FitPop(arr)
{
	if (arr.length != 0) {
		var result = arr[arr.length-1];
		arr.length = arr.length-1;
		
		return result;
	}
	
	return;
}

/**
 *
 * FitTop(array)
 *
 * array: the array to get the top
 * returns the topmost element
 */

function FitTop(arr)
{
	if (arr.length > 0) {
		return arr[arr.length - 1];
	}
	
	return;
}

/**
 *
 * FitJoin(array,char)
 *
 * array: the array to join
 * returns the string
 */

function FitJoin(arr,c)
{
	var ret = "";
	var i = 0;
	
	for (i = 0; i < arr.length; i++){
		if (ret != "") {
			ret += c;
		}
		ret += arr[i];
	}
	
	return ret;
}

/**
 *
 * FitUrlParser(url)
 *
 * url: the url to parse
 *
 * usage: var purl = new FitUrlParser(url);
 *
 */

function FitUrlParser(url)
{
	var tmp_array;

	this.hash = "";
	this.host = "";
	this.hostname = "";
	this.domain = "";
	this.href = "";
	this.pathname = "";
	this.port = "";
	this.protocol = "";
	this.search = "";
	
	this.directory = "";
	this.subdirectory = "";
	this.filename = "";
	this.shortname = "";
	this.extension = "";
		
	this.href = url;
	tmp_array = this.href.split("#");
	this.hash = tmp_array[1] ? '#'+tmp_array[1] : "";
	tmp_array = tmp_array[0].split("?");
	this.search = tmp_array[1] ? "?"+tmp_array[1] : "";
	tmp_array = tmp_array[0].split("//");
	this.protocol = tmp_array[0];
	this._is_fullPath = (this.protocol == 'http:' || this.protocol == 'https:' || this.protocol == 'file:' || this.protocol == 'mms:') ? true : false;
	this.protocol = (this._is_fullPath) ? this.protocol : "";

	if (!this.protocol) {
		return;
	}

	if (!this._is_fullPath) {
		this.pathname = tmp_array[0] || "";
		this.host = "";
		this.port = "";
	} else if (tmp_array.length >= 2) {
		tmp_array = tmp_array[1].split("/");
		var _temp = tmp_array[0];

		FitShift(tmp_array);
		this.pathname = "/" + tmp_array.join("/");

		tmp_array = _temp.split(":");
		this.hostname = tmp_array[0];

		// set domain to hostname.
		this.domain = this.hostname;
		this.port = (this.protocol == "http:") ? (tmp_array[1]) ? tmp_array[1] : "80" : "";
		
		if (!this.port) {
			this.port = (this.protocol == "https:" ) ? (tmp_array[1]) ? tmp_array[1] : "443" : "";
		}
		
	    if (this.port == 80 || this.port == 443) {
			this.host = this.hostname;
		} else {
			this.host = this.hostname + ":" + this.port;
		}
	}

	if (this.pathname) {
		tmp_array = this.pathname.split("/");

		if (tmp_array[tmp_array.length - 1].length > 0) {
			this.filename = tmp_array[tmp_array.length - 1];
			FitPop(tmp_array);
		}
		
		while (tmp_array.length>0 && FitTop(tmp_array) == "") {
			FitPop(tmp_array);
		}
		
		if (tmp_array.length > 0) {
			this.subdirectory = tmp_array[tmp_array.length - 1];
			this.directory = '/' + FitJoin(tmp_array, '/');
		}

		if (this.directory.length == 0) {
			this.directory = '/';
		}

		if (this.filename) {
			tmp_array = this.filename.split(".");
			this.extension = (tmp_array[tmp_array.length - 1]) ? "." + tmp_array[tmp_array.length - 1] : "";
			FitPop(tmp_array);
			this.shortname = tmp_array.join(".");
		}
	}
	
	return false;
}

/**
 *
 * FitReplaceAttribute
 *
 * target, tag, key, value
 */

function FitReplaceAttribute(target, tag, key, value)
{
	var mykey = target.toLowerCase() + "_" + tag.toLowerCase() + "_" + key.toLowerCase() + "_" + value.toLowerCase();
	
	return sv_replaceAttributes[mykey] || value;
}

/**
 * Adjust forms,images,layers and frames indexes
 *
 * index, jsarray, target
 */

function FitTransIndex(index, jsarray, target) 
{  
	if (typeof(index) != "number") {
		return index;
	} else {
		switch (jsarray) {
			case "forms":
				var scan = target + "-" + index;
				var i = 0;
				while (sv_jsIndex[i]) {
					if (sv_jsIndex[i] == scan) {
						return i;
					}
					i++;
				}
				return index;
			case "images":		
			case "layers":
			case "frames":	
				return index;
		}
	}
} 

function FitEncodeQuery(str) 
{
	var start = str.indexOf('?');
	var end = str.lastIndexOf('?');
	
	while (start != end) {
		var first = str.substring(0, start);
		var last = str.substr(start + 1);
		str = first+fitQMEncoder + last;
		start = str.indexOf('?');
		end = str.lastIndexOf('?');
	}
	
	return str;
}

function FitCheckTemplateParam(str) 
{
	var i = 1;
	var paramurl = '';
	var param = '';
	
	do {
		param = fitUrlSeparator + 'template' + i;
		paramurl = FitGetParam(str, param);
	} while (paramurl != '' && paramurl != sv_full_url['template']);
	
	if (paramurl == sv_full_url['template']) {
		return param;
	}
	
	return '';
}

function FITRemoveReferrer(str)
{
	if (typeof(str) != "string") {
		return str;
	}
	
	if (str.indexOf("/originalreferrer") != -1) {
		return str.substr(0, str.indexOf("/originalreferrer"));
	}
	
	return str;
}

function FITLeftTruncMatch(str, right) 
{
	var r = str.lastIndexOf(right);
	
	if (r == -1) {
		return false;
	} else if (str.length == r + right.length) {
		return true;
	}
	
	return false;
}

