function HashMap(){
  var separator='&';
  var keySeparator='=';
  var keys=new Array();
  var values=new Array();
  this.size=function(){
    return keys.length;
  }
  this.clear=function(){
    delete keys;keys=new Array();
    delete values;values=new Array();
  }
  this.containsKey=function(key){
    var i=getIndex(key,keys);
    if(i<0)return false;
    return true;
  }
  this.containValue=function(value){
    var i=getIndex(value,values);
    if(i<0)return false;
    return true;
  }
  this.set=function(key,value){
    var i=getIndex(key,keys);
    if(i<0){
      keys.push(key);
      values.push(value);
    } else{
      values[i]=value;
    }
    return;
  }
  this.get=function(key){
    var i=getIndex(key,keys);
    if(i<0)return null;
    return values[i];
  }
  this.remove=function(key){
    var i=getIndex(key,keys);
    if(i<0)return;
    keys.splice(i,1);
    values.splice(i,1);   
    return;
  }
  this.getKeys=function(){return keys;}
  this.getValues=function(){return values;}
  this.toString=function(_separator,_keySeparator){
    return getString(_separator,_keySeparator,false);
  }
  this.escapeString=function(_separator,_keySeparator){
    return getString(_separator,_keySeparator,true);
  }
  function getString(_separator,_keySeparator,_e){
    _separator=_separator||separator;
    _keySeparator=_keySeparator||keySeparator;
    if(keys.length==0)return '';
    var str='';
    for(var i=0;i<keys.length;i++){
      str+=_separator+keys[i]+_keySeparator+getStr(values[i]);
    }
    return str.substr(1);
    function getStr(v){
      var s=''
      if(v.constructor==String||v.constructor==Number||v.constructor==Boolean){
        s=(_e)?escape(v):v;
      }else if(v.constructor==Array){
        for(var i=0;i<v.length;i++)s+=','+getStr(v[i]);
        s=s.substr(1);
      }else{
        s=typeof(v);
      }
      return s;
    }
  }
  this.toJson=function(){
    if(keys.length==0)return '{}';
    var str='';
    for(var i=0;i<keys.length;i++){
      str+=','+keys[i]+':'+getStr(values[i]);
    }
    return '{'+str.substr(1)+'}';
    function getStr(v){
      var s='';
      if(v==null||v.constructor==Number||v.constructor==Boolean){
        s=v;
      }else if(v.constructor==String){
        s='\''+v.replace("'","\\'")+'\'';
      }else if(v.constructor==Array){
        for(var i=0;i<v.length;i++)s+=','+getStr(v[i]);
        s='['+s.substr(1)+']';
      }else if(v.constructor==Object){
        for(var i in v)s+=','+i+':'+getStr(v[i]);
        s='{'+s.substr(1)+'}';
      }else{
        s='\''+typeof(v)+'\'';
      }
      return s;
    }
  }
  this.concat=function(_map){
    var ks=this.getKeys().concat(_map.getKeys());
    var vs=this.getValues().concat(_map.getValues());
    this.clear();
    for(var i=0;i<ks.length;i++){
      this.set(ks[i],vs[i]);
    }
    return this;
  }
  this.readString=function(str,_separator,_keySeparator){
    _separator=_separator||separator;
    _keySeparator=_keySeparator||keySeparator;
    if(str==null || str=='')return;
    var aryA=str.split(_separator);
    for(var i=0;i<aryA.length;i++){
      var aryB=aryA[i].split(_keySeparator);
      if(aryB[0]!=''){
        keys.push(aryB[0].replace(/^\s+|\s+$/g,''));
        values.push(aryB[1]);
      }
    }
  }
  function getIndex(str,ary){
    for(var i=0;i<ary.length;i++)if(ary[i]==str)return i;
    return -1;
  }
}