JS.Set=new JS.Class('Set',{extend:{forEach:function(a,b,c){if(!a||!b)return;if(a.forEach)return a.forEach(b,c);for(var d=0,e=a.length;da._0.length&&this.isSuperset(a)},isSubset:function(b){var c=true;this.forEach(function(a){if(!c)return;if(!b.contains(a))c=false});return c},isSuperset:function(a){return a.isSubset(this)},merge:function(b){this.klass.forEach(b,function(a){this.add(a)},this)},product:function(c){var d=new JS.Set;this.forEach(function(b){this.klass.forEach(c,function(a){d.add([b,a])})},this);return d},rebuild:function(){var a=this._0;this.clear();this.merge(a)},remove:function(a){var b=this._1(a);if(b===-1)return;this._0.splice(b,1);this.length=this.size=this._0.length},removeIf:function(a,b){if(!a)return this.enumFor('removeIf');a=JS.Enumerable.toFn(a);var c=this._0,d=c.length;while(d--){if(a.call(b||null,c[d]))this.remove(c[d])}return this},replace:function(a){this.clear();this.merge(a)},subtract:function(b){this.klass.forEach(b,function(a){this.remove(a)},this)},union:function(a){var b=new this.klass;b.merge(this);b.merge(a);return b},xor:function(b){var c=new JS.Set(b);this.forEach(function(a){c[c.contains(a)?'remove':'add'](a)});return c},_1:function(a){var b=this._0.length,c=JS.Enumerable.areEqual;while(b--){if(c(a,this._0[b]))return b}return-1}});JS.Set.include({n:JS.Set.instanceMethod('intersection'),u:JS.Set.instanceMethod('union'),x:JS.Set.instanceMethod('product')},false);JS.SortedSet=new JS.Class('SortedSet',JS.Set,{extend:{compare:function(a,b){return JS.isType(a,Object)?a.compareTo(b):(ab?1:0))}},add:function(a){var b=this._1(a,true);if(b===null)return;this._0.splice(b,0,a);this.length=this.size=this._0.length},_1:function(a,b){var c=this._0,d=c.length,e=0,f=d,g=this.klass.compare,h=JS.Enumerable.areEqual,i;if(d===0)return b?0:-1;if(g(a,c[0])<1){f=0;e=0}if(g(a,c[d-1])>0){f=0;e=d}while(!h(a,c[e])&&f>0.5){f=f/2;e+=(g(a,c[e])>0?1:-1)*Math.round(f);if(e>0&&g(a,c[e-1])>0&&g(a,c[e])<1)f=0}while(c[e]&&!h(a,c[e])&&g(a,c[e])===0)e+=1;i=h(a,c[e]);return b?(i?null:e):(i?e:-1)}});JS.HashSet=new JS.Class('HashSet',JS.Set,{forEach:function(a,b){if(!a)return this.enumFor('forEach');a=JS.Enumerable.toFn(a);this._0.forEachKey(a,b);return this},add:function(a){if(this.contains(a))return false;this._0.store(a,true);this.length=this.size=this._0.length;return true},clear:function(){this._0=new JS.Hash();this.size=this.length=0},contains:function(a){return this._0.hasKey(a)},rebuild:function(){this._0.rehash();this.length=this.size=this._0.length},remove:function(a){this._0.remove(a);this.length=this.size=this._0.length},removeIf:function(b,c){if(!b)return this.enumFor('removeIf');b=JS.Enumerable.toFn(b);this._0.removeIf(function(a){return b.call(c||null,a.key)});this.length=this.size=this._0.length;return this}});JS.Enumerable.include({toSet:function(a,b,c){a=a||JS.Set;return new a(this,b,c)}},true);