function cmxUri(uri)
{
	var u = new String(uri);
	var protocolEnd = u.indexOf("://");
	
	//strip trailing "/" if applicable
	if (u.indexOf("/", protocolEnd + 3) == u.length - 1)
		u = u.substr(0, u.length - 1);

	var tldnEnd = (u.indexOf("/", protocolEnd + 3) > -1) ? u.indexOf("/", protocolEnd + 3) : u.length;
	var host = new String(u.substring(protocolEnd + 3, tldnEnd));
	var domainParts = new Array();
	domainParts = host.split(".");
	var qStart = (u.indexOf("?", protocolEnd + 3) > -1) ? u.indexOf("?", protocolEnd + 3) : u.length;
	var query = u.substring(qStart + 1);
	
	this.absolutePath = u.substring(tldnEnd, qStart);
	this.path = this.absolutePath.substr(this.absolutePath.lastIndexOf('/'), this.absolutePath.length);
	this.absoluteUri = u.substring(0, qStart);
	this.host = host;
	this.query = query;
	this.pathAndQuery = (this.query != '') ? this.absolutePath + "?" + this.query : this.absolutePath;
	this.protocol = u.substr(0, protocolEnd);
	this.tldn = domainParts[domainParts.length - 1];
	this.isValidUri = (this.protocol != "") && (this.host != "");
	
	this.queryString = new QueryString(query);
				
	function QueryString(qs)
	{
		this.keys = new Array()
		this.values = new Array()

		var query = new String(qs);
		var pairs = query.split("&");

		for (var i = 0; i < pairs.length; i++)
		{
			var pos = pairs[i].indexOf('=');
			if (pos >= 0)
			{
				var argname = pairs[i].substring(0, pos);
				var value = pairs[i].substring(pos + 1);
				this.keys[this.keys.length] = argname;
				this.values[this.values.length] = value;		
			}
		}

		this.item = function(key)
			{
				for (var i = 0; i < this.keys.length; i++)
					if (this.keys[i] == key)
						return this.values[i];

				return null;
			};
		
		this.containsKey = function(key)
			{
				for (var i = 0; i < this.keys.length; i++)
					if (this.keys[i] == key)
						return true;
				
				return false;
			};
	}
}
