function Resize(res, oTimer, oMoveable, type){
	this.elem = res instanceof resizeable ? res.elem : res;
	this.resizeable = res instanceof resizeable ? res : new resizeable(res, type);
	this.timer = Timer.detectTimer(oTimer);
	if(this.timer._MUTUAL){
		if(this.timer.registerResize){
			this.timer.registerResize(this);
		}else{
			Resize.handleMutualTimer(this.timer);
			this.timer.registerResize(this);
		}
	}else{
		this.timer.registerEvent({
			name: "resize", 
			func: function(){
				this.resizeable.resizeBy(this.stepX, this.stepY);
			},
			oThis: this,
			args: []
		});
	}
	if(typeof oMoveable == "object" && oMoveable instanceof moveable){
		this.resizeable.addMoveable(oMoveable);
	}else if(typeof oMoveable == "boolean"){
		if(oMoveable){
			this.resizeable.addMoveable(new moveable(this.elem));
		}
	}
	this.stepLeft = 0;
	this.stepUp = 0;
	this.stepDown = 0;
	this.stepRight = 0;
	this.stepX = 0;
	this.stepY = 0;
	this.onresize = DOMEvent.cloneEvent(this.resizeable.onresize, this);
	this.onafterresize = DOMEvent.cloneEvent(this.resizeable.onafterresize, this);
	this.onzerowidth = DOMEvent.cloneEvent(this.resizeable.onzerowidth, this);
	this.onzeroheight = DOMEvent.cloneEvent(this.resizeable.onzeroheight, this);
	this.onstop = new DOMEvent(this);
	this.onstart = new DOMEvent(this);
	if(!this.resizeable.moveable){
		this.resizeLeft = this.resizeUp = function(){return false}
	}
	if(this.constructor._TO_INSTANCES){
		this.constructor._instances.push(this);
	}
}
Resize.prototype.setSteps = function(x, y){
	this.stepX = x;
	this.stepY = y;
}
Resize.prototype.start = function(){
	if(!this.timer._MUTUAL){
		this.timer.start();
	}
	this.IS_DOING = true;
	this.onstart.fire();
}
Resize.prototype.resizeLeft = function(value){
	this.stepLeft = value;
	this.stepX = value + this.stepRight;
	this.resizeable._CHANGE_MOVEABLE = -1;
}
Resize.prototype.resizeUp = function(value){
	this.stepUp = value;
	this.stepY = value + this.stepDown;
	this.resizeable._CHANGE_MOVEABLE = -1;
}
Resize.prototype.resizeRight = function(value){
	this.stepRight = value;
	this.stepX = value + this.stepLeft;	
	this.resizeable._CHANGE_MOVEABLE = 0;
}
Resize.prototype.resizeDown = function(value){
	this.stepDown = value;
	this.stepY = value + this.stepUp;	
	this.resizeable._CHANGE_MOVEABLE = 0;
}
Resize.prototype.stopLeft = function(){
	this.stepX -= this.stepLeft;
	this.stepLeft = 0;
	this.onresize.remove(Resize._RES_LEFT.name);
}
Resize.prototype.stopUp = function(){
	this.stepY -= this.stepUp;
	this.stepUp = 0;
	this.onresize.remove(Resize._RES_UP.name);
}
Resize.prototype.stopRight = function(){
	this.stepX -= this.stepRight;
	this.stepRight = 0;
}
Resize.prototype.stopDown = function(){
	this.stepY -= this.stepDown;
	this.stepDown = 0;
}
Resize.prototype.stop = function(){
	this.onresize.remove(Resize._RES_LEFT.name);
	this.onresize.remove(Resize._RES_UP.name);
	if(!this.timer._MUTUAL){
		this.timer.clear();
	}
	this.IS_DOING = false;
	this.onstop.fire();
}
Resize.prototype.setLimits = function(type, value, startValue){
	this.resizeable.setLimits(type, value, startValue);
	var PRESETS = resizeable.LIMITS[type];
	this[PRESETS.onless] = DOMEvent.cloneEvent(this.resizeable[PRESETS.onless], this);
	this[PRESETS.onmore] = DOMEvent.cloneEvent(this.resizeable[PRESETS.onmore], this);
}
Resize.prototype.setResizeSpace = function(X, Y, sX, sY){
	this.moveSpace = this.resizeable.setResizeSpace(X, Y, sX, sY);
	if(!this.onresizespacereach){
		this.onresizespacereach = DOMEvent.cloneEvent(this.resizeable.onresizespacereach, this);
	}
}
Resize.prototype.invertSteps = function(){
	this.stepX = -this.stepX;
	this.stepY = -this.stepY;
}
Resize.prototype.set = function(param){
	this.resizeable.set(param);
}
Resize.prototype.unset = function(){
	this.resizeable.unset();
}
Resize.prototype.toString = __toString;
Resize.prototype.__name = "Resize";
Resize.handleMutualTimer = function(oTimer){
	if(oTimer.registerResize){
		return;
	}
	oTimer.resizes = [];
	oTimer.registerResize = function(oR){
		this.resizes.push(oR);
	}
	oTimer.registerEvent(
	{
		name: "resize",
		func: function(){
			this.resizes.each(function(res){
				if(res.IS_DOING){
					res.resizeable.resizeBy(res.stepX, res.stepY);
				}
			})
		}, 
		oThis: oTimer,
		args: [],
		freq: Resize.frequency
	}
	)
}
Resize.frequency = 1;
Resize._RES_LEFT = {
	name: "resize-left",
	func: function(){
		this.moveable.moveBy(-this.stepLeft, 0);
	}
}
Resize._RES_UP = {
	name: "resize-top",
	func: function(){
		this.moveable.moveBy(0, -this.stepUp);
	}
}
Resize.setGrow = function(oResize){
	oResize.Grow = {};
	oResize.ongrown = new DOMEvent();
	oResize.ongrown.register("stop", Resize.defaultOnGrown.bind(oResize))
	oResize.growTo = function(toW, toH, speed){
		speed = speed ? speed : 3;
		var currentWidth = this.resizeable.width;
		var currentHeight = this.resizeable.height;
		var deltaWidth = toW - currentWidth;
		var deltaHeight = toH - currentHeight;
		if(!deltaWidth && !deltaHeight){
			return;
		}
		this.deltaWidth = deltaWidth;
		this.deltaHeight = deltaHeight;
		this.toW = toW;
		this.toH = toH;
		var biggerDelta = Math.abs(deltaWidth) > Math.abs(deltaHeight) ? deltaWidth : deltaHeight;
		var numOfSteps = Math.abs(Math.round(biggerDelta / speed));
		var stepX = deltaWidth / (numOfSteps);
		var stepY = deltaHeight / (numOfSteps);
		this.Grow.grownX = 0;
		this.Grow.grownY = 0;
		this.Grow.deltaWidth = deltaWidth;
		this.Grow.deltaHeight = deltaHeight;
		this.Grow.stepX = stepX;
		this.Grow.stepY = stepY;
		this.stepX = stepX;
		this.stepY = stepY;
		this.numOfSteps = numOfSteps;

		this.onresize.register("grow-to", function(oR, oG){
			var STOP_X = false, STOP_Y = false;
			if(Math.abs(oG.grownX + oG.stepX) >= Math.abs(oG.deltaWidth)){
				var sX = (Math.abs(oG.deltaWidth) - Math.abs(oG.grownX))  / oG.stepX.signOf();
				STOP_X = true;
			}
			if(Math.abs(oG.grownY + oG.stepY) >= Math.abs(oG.deltaHeight)){
				var sY = (Math.abs(oG.deltaHeight) - Math.abs(oG.grownY))  / oG.stepY.signOf();
				oG.stepY = sY;
				STOP_Y = true;
			}
			oG.grownX += oG.stepX;
			oG.grownY += oG.stepY;
			if(STOP_X && STOP_Y){
				this.ongrown.fire();
			}

		}.bind(this, this.resizeable, this.Grow));
		this.start();
	}
}
Resize.defaultOnGrown = function(){
	this.onresize.remove("grow-to");
	this.stop();
}
Resize._instances = [];
Resize._TO_INSTANCES = true;