|  | @@ -164,29 +164,56 @@ function Smalltalk(){
 | 
	
		
			
				|  |  |  	/* Initialize a class in its class hierarchy. Handle both class and
 | 
	
		
			
				|  |  |  	   metaclasses. */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	st.init = function(klass) {
 | 
	
		
			
				|  |  | -		var subclasses = st.subclasses(klass);
 | 
	
		
			
				|  |  | -		var methods;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		if(klass.superclass && klass.superclass !== nil) {
 | 
	
		
			
				|  |  | -			methods = st.methods(klass.superclass);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			//Methods linking
 | 
	
		
			
				|  |  | -			for(var i in methods) {
 | 
	
		
			
				|  |  | -				if(!klass.fn.prototype.methods[i]) {
 | 
	
		
			
				|  |  | -					klass.fn.prototype.inheritedMethods[i] = methods[i];
 | 
	
		
			
				|  |  | -					klass.fn.prototype[methods[i].jsSelector] = methods[i].fn;
 | 
	
		
			
				|  |  | +	if ('function' === typeof Object.keys) {
 | 
	
		
			
				|  |  | +		st.init = function(klass) {
 | 
	
		
			
				|  |  | +			var subclasses = st.subclasses(klass);
 | 
	
		
			
				|  |  | +			var methods, proto = klass.fn.prototype;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			if(klass.superclass && klass.superclass !== nil) {
 | 
	
		
			
				|  |  | +				methods = st.methods(klass.superclass);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				//Methods linking
 | 
	
		
			
				|  |  | +				for(var keys=Object.keys(methods),i=0,l=keys.length; i<l; ++i) {
 | 
	
		
			
				|  |  | +					var k = keys[i]
 | 
	
		
			
				|  |  | +					if(!proto.methods[k]) {
 | 
	
		
			
				|  |  | +						proto.inheritedMethods[k] = methods[k];
 | 
	
		
			
				|  |  | +						proto[methods[k].jsSelector] = methods[k].fn;
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  |  				}
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		for(var i=0;i<subclasses.length;i++) {
 | 
	
		
			
				|  |  | -			st.init(subclasses[i]);
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		if(klass.klass && !klass.meta) {
 | 
	
		
			
				|  |  | -			st.init(klass.klass);
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | +			for(var i=0;i<subclasses.length;i++) {
 | 
	
		
			
				|  |  | +				st.init(subclasses[i]);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			if(klass.klass && !klass.meta) {
 | 
	
		
			
				|  |  | +				st.init(klass.klass);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		};
 | 
	
		
			
				|  |  | +	} else {
 | 
	
		
			
				|  |  | +		st.init = function(klass) {
 | 
	
		
			
				|  |  | +			var subclasses = st.subclasses(klass);
 | 
	
		
			
				|  |  | +			var methods, proto = klass.fn.prototype;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			if(klass.superclass && klass.superclass !== nil) {
 | 
	
		
			
				|  |  | +				methods = st.methods(klass.superclass);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				//Methods linking
 | 
	
		
			
				|  |  | +				for(var i in methods) {
 | 
	
		
			
				|  |  | +					if(!proto.methods[i]) {
 | 
	
		
			
				|  |  | +						proto.inheritedMethods[i] = methods[i];
 | 
	
		
			
				|  |  | +						proto[methods[i].jsSelector] = methods[i].fn;
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			for(var i=0;i<subclasses.length;i++) {
 | 
	
		
			
				|  |  | +				st.init(subclasses[i]);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			if(klass.klass && !klass.meta) {
 | 
	
		
			
				|  |  | +				st.init(klass.klass);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		};
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* Answer all registered Packages as Array */
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -201,27 +228,55 @@ function Smalltalk(){
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* Answer all registered Smalltalk classes */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	st.classes = function() {
 | 
	
		
			
				|  |  | -		var classes = [];
 | 
	
		
			
				|  |  | -		for(var i in st) {
 | 
	
		
			
				|  |  | -			if(i.search(/^[A-Z]/g) != -1) {
 | 
	
		
			
				|  |  | -				classes.push(st[i]);
 | 
	
		
			
				|  |  | +	if ('function' === typeof Object.keys) {
 | 
	
		
			
				|  |  | +		st.classes = function() {
 | 
	
		
			
				|  |  | +			var classes = [], names = Object.keys(st), l = names.length;
 | 
	
		
			
				|  |  | +			for (var i=0; i<l; ++i) {
 | 
	
		
			
				|  |  | +				var name = names[i];
 | 
	
		
			
				|  |  | +				if (name.search(/^[A-Z]/) !== -1) {
 | 
	
		
			
				|  |  | +					classes.push(st[name]);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		return classes
 | 
	
		
			
				|  |  | -	};
 | 
	
		
			
				|  |  | +			return classes;
 | 
	
		
			
				|  |  | +		};
 | 
	
		
			
				|  |  | +	} else {
 | 
	
		
			
				|  |  | +		st.classes = function() {
 | 
	
		
			
				|  |  | +			var classes = [];
 | 
	
		
			
				|  |  | +			for(var i in st) {
 | 
	
		
			
				|  |  | +				if(i.search(/^[A-Z]/g) != -1) {
 | 
	
		
			
				|  |  | +					classes.push(st[i]);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			return classes
 | 
	
		
			
				|  |  | +		};
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* Answer all methods (included inherited ones) of klass. */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	st.methods = function(klass) {
 | 
	
		
			
				|  |  | -		var methods = {};
 | 
	
		
			
				|  |  | -		for(var i in klass.fn.prototype.methods) {
 | 
	
		
			
				|  |  | -			methods[i] = klass.fn.prototype.methods[i]
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		for(var i in klass.fn.prototype.inheritedMethods) {
 | 
	
		
			
				|  |  | -			methods[i] = klass.fn.prototype.inheritedMethods[i]
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		return methods;
 | 
	
		
			
				|  |  | +	if ('function' === typeof Object.keys) {
 | 
	
		
			
				|  |  | +		st.methods = function(klass) {
 | 
	
		
			
				|  |  | +			var methods = {};
 | 
	
		
			
				|  |  | +			var copyFrom = klass.fn.prototype.methods;
 | 
	
		
			
				|  |  | +			for(var i=0, k=Object.keys(copyFrom), l=k.length; i<l; ++i) {
 | 
	
		
			
				|  |  | +				methods[k[i]] = copyFrom[k[i]];
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			copyFrom = klass.fn.prototype.inheritedMethods;
 | 
	
		
			
				|  |  | +			for(var i=0, k=Object.keys(copyFrom), l=k.length; i<l; ++i) {
 | 
	
		
			
				|  |  | +				methods[k[i]] = copyFrom[k[i]];
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			return methods;
 | 
	
		
			
				|  |  | +		};
 | 
	
		
			
				|  |  | +	} else {
 | 
	
		
			
				|  |  | +		st.methods = function(klass) {
 | 
	
		
			
				|  |  | +			var methods = {};
 | 
	
		
			
				|  |  | +			for(var i in klass.fn.prototype.methods) {
 | 
	
		
			
				|  |  | +				methods[i] = klass.fn.prototype.methods[i]
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			for(var i in klass.fn.prototype.inheritedMethods) {
 | 
	
		
			
				|  |  | +				methods[i] = klass.fn.prototype.inheritedMethods[i]
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			return methods;
 | 
	
		
			
				|  |  | +		};
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* Answer the direct subclasses of klass. */
 | 
	
	
		
			
				|  | @@ -229,15 +284,17 @@ function Smalltalk(){
 | 
	
		
			
				|  |  |  	st.subclasses = function(klass) {
 | 
	
		
			
				|  |  |  		var subclasses = [];
 | 
	
		
			
				|  |  |  		var classes = st.classes();
 | 
	
		
			
				|  |  | -		for(var i in classes) {
 | 
	
		
			
				|  |  | -			if(classes[i].fn) {
 | 
	
		
			
				|  |  | -				//Metaclasses
 | 
	
		
			
				|  |  | -				if(classes[i].klass && classes[i].klass.superclass === klass) {
 | 
	
		
			
				|  |  | -					subclasses.push(classes[i].klass);
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | +		for(var i=0, l=classes.length; i<l; ++i) {
 | 
	
		
			
				|  |  | +			var c = classes[i]
 | 
	
		
			
				|  |  | +			if(c.fn) {
 | 
	
		
			
				|  |  |  				//Classes
 | 
	
		
			
				|  |  | -				if(classes[i].superclass === klass) {
 | 
	
		
			
				|  |  | -					subclasses.push(classes[i]);
 | 
	
		
			
				|  |  | +				if(c.superclass === klass) {
 | 
	
		
			
				|  |  | +					subclasses.push(c);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				c = c.klass;
 | 
	
		
			
				|  |  | +				//Metaclasses
 | 
	
		
			
				|  |  | +				if(c && c.superclass === klass) {
 | 
	
		
			
				|  |  | +					subclasses.push(c);
 | 
	
		
			
				|  |  |  				}
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  		}
 |