function URIParser(url) {
  // setup new class
  this.init()
  this.uri = url;
  // alert(this.uri);
  if (this.uri != "") this.parseURI(this.uri);
}
URIParser.prototype.init = function() {
  this.uri = "";       // 'http://www.homegain.com/one/two/three/index.html?one=1&two=2
  this.method = "";               // 'http://'
  this.server = "";               // 'www.homegain.com'
  this.path = "";                 // '/one/two/three'
  this.arg_list = new Array();    // [ 'one', 'two' ]
  this.args = new Object();       // { 'one':'1', 'two':'2' }
  this.args_exist = false;       // { 'one':'1', 'two':'2' }
  this.valid = true;
}
URIParser.prototype.parseURI = function(uri) {
  // create an object with server, path, page, parameters, anchor
  if (uri == undefined) return;
  this.uri = uri;
  var tmp = "";   // temporary workspace
  // needed to split the URL up before
  var page_pieces = this.uri.split("?");
  var page_url = page_pieces[0];
  var page_args = page_pieces[1];
  if (page_args != undefined &&
      page_args.length > 0) {
    this.parseArgs(page_args);
  }
  // split up method
  // get URL method
  if (page_url.substr(0,1) == '\/') {
    // this is a relative URL
    this.method = "";
    this.server = "";
    this.path = page_url;
    return;
  } else if (page_url.substr(0,7) == 'http:\/\/') {
    // method is http:// or ftp://
    //   TODO: add other methods in an else or reg exp on ://
    this.method = page_url.substr(0,7);
    var tmp = page_url.substr(7);
  } else {
    this.valid = false;
    return;
  }
  // we need to grab server and path
  var chk_slashes = tmp.indexOf('\/');
  if (chk_slashes == -1) {
    // have 'www.krunch.com'
    this.server = tmp;
    this.path = "";
  } else {
    // have 'www.krunch.com/something/else'
    this.server = tmp.substr(0, chk_slashes);
    this.path = tmp.substr(chk_slashes);
  }
}
URIParser.prototype.parseArgs = function(args) {
  // string of key value pairs
  var kv_pair = args.split('&');
  if (kv_pair.length == 0) return;
  var key,value;
  for (i=0; i< kv_pair.length; i++) {
    param = kv_pair[i].split("=");
    if (param.length == 2) {
      key = param[0]; value = param[1];
    } else { 
      key = param[0]; value = "";
    }
    this.arg_list.push(key);
    this.args[key] = value;
  }
  this.args_exist = true;
}
URIParser.prototype.addParameter = function(key, value) {
  this.arg_list.push(key);
  this.args[key] = value;
}
URIParser.prototype.hasParameter = function(key) {
  for (property in this.args) {
    if (property == key) return 1;
  }
  return 0;
}
URIParser.prototype.getParameter = function(key) {
  return this.args[key];
}
URIParser.prototype.setParameter = function(key, value) {
  return this.args[key] = value;
}
URIParser.prototype.isValid = function(key) {
  return this.valid;
}
URIParser.prototype.toString = function() {
  var url = ""
  url += this.method;
  url += this.server;
  if (this.path != "") url += this.path;
  // make 'correct' URL -
  //    only put on slash if:
  if (this.args_exist == false &&
      this.arg_list.length > 0 &&
      this.path.substr(this.path.length-1) != '/' &&
      this.path.length < 2) {
    url += '/';
  }
  cnt = 0;
  if (this.arg_list.length > 0) { url += "?" };
  for (property in this.args) {
    cnt += 1;
    url += property + "=" + this.args[property];
    if (cnt < this.arg_list.length) url += "&";
  }
  return url;
};
