text: define([
  	"../_base/declare",
  	"../dom-geometry", "../dom-style",
  	"./common", "./Mover", "./Moveable"
  ], function(declare, domGeom, domStyle, dnd, Mover, Moveable){
  
  // module:
  //		dojo/dnd/move
  
  /*=====
  var __constrainedMoveableArgs = declare([Moveable.__MoveableArgs], {
  	// constraints: Function
  	//		Calculates a constraint box.
  	//		It is called in a context of the moveable object.
  	constraints: function(){},
  
  	// within: Boolean
  	//		restrict move within boundaries.
  	within: false
  });
  =====*/
  
  var constrainedMoveable = declare("dojo.dnd.move.constrainedMoveable", Moveable, {
  	// object attributes (for markup)
  	constraints: function(){},
  	within: false,
  
  	constructor: function(node, params){
  		// summary:
  		//		an object that makes a node moveable
  		// node: Node
  		//		a node (or node's id) to be moved
  		// params: __constrainedMoveableArgs?
  		//		an optional object with additional parameters;
  		//		the rest is passed to the base class
  		if(!params){ params = {}; }
  		this.constraints = params.constraints;
  		this.within = params.within;
  	},
  	onFirstMove: function(/*Mover*/ mover){
  		console.log("dojo.dnd.onFirstMove    mover: " + mover);
  		// summary:
  		//		called during the very first move notification;
  		//		can be used to initialize coordinates, can be overwritten.
  		var c = this.constraintBox = this.constraints.call(this, mover);
  		c.r = c.l + c.w;
  		c.b = c.t + c.h;
  		if(this.within){
  			var mb = domGeom.getMarginSize(mover.node);
  			c.r -= mb.w;
  			c.b -= mb.h;
  		}
  	},
  	onMove: function(/*Mover*/ mover, /*Object*/ leftTop){
  		console.log("dojo.dnd.onMove    mover: " + mover);
  		// summary:
  		//		called during every move notification;
  		//		should actually move the node; can be overwritten.
  		var c = this.constraintBox, s = mover.node.style;
  		this.onMoving(mover, leftTop);
  		leftTop.l = leftTop.l < c.l ? c.l : c.r < leftTop.l ? c.r : leftTop.l;
  		leftTop.t = leftTop.t < c.t ? c.t : c.b < leftTop.t ? c.b : leftTop.t;
  		s.left = leftTop.l + "px";
  		s.top  = leftTop.t + "px";
  		this.onMoved(mover, leftTop);
  	}
  });
  
  /*=====
  var __boxConstrainedMoveableArgs = declare([__constrainedMoveableArgs], {
  	// box: Object
  	//		a constraint box
  	box: {}
  });
  =====*/
  
  var boxConstrainedMoveable = declare("dojo.dnd.move.boxConstrainedMoveable", constrainedMoveable, {
  	// box:
  	//		object attributes (for markup)
  	box: {},
  
  	constructor: function(node, params){
  		// summary:
  		//		an object, which makes a node moveable
  		// node: Node
  		//		a node (or node's id) to be moved
  		// params: __boxConstrainedMoveableArgs?
  		//		an optional object with parameters
  		var box = params && params.box;
  		this.constraints = function(){ return box; };
  	}
  });
  
  /*=====
  var __parentConstrainedMoveableArgs = declare( [__constrainedMoveableArgs], {
  	// area: String
  	//		A parent's area to restrict the move.
  	//		Can be "margin", "border", "padding", or "content".
  	area: ""
  });
  =====*/
  
  var parentConstrainedMoveable = declare("dojo.dnd.move.parentConstrainedMoveable", constrainedMoveable, {
  	// area:
  	//		object attributes (for markup)
  	area: "content",
  
  	constructor: function(node, params){
  		// summary:
  		//		an object, which makes a node moveable
  		// node: Node
  		//		a node (or node's id) to be moved
  		// params: __parentConstrainedMoveableArgs?
  		//		an optional object with parameters
  		var area = params && params.area;
  		this.constraints = function(){
  			var n = this.node.parentNode,
  				s = domStyle.getComputedStyle(n),
  				mb = domGeom.getMarginBox(n, s);
  			if(area == "margin"){
  				return mb;	// Object
  			}
  			var t = domGeom.getMarginExtents(n, s);
  			mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
  			if(area == "border"){
  				return mb;	// Object
  			}
  			t = domGeom.getBorderExtents(n, s);
  			mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
  			if(area == "padding"){
  				return mb;	// Object
  			}
  			t = domGeom.getPadExtents(n, s);
  			mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
  			return mb;	// Object
  		};
  	}
  });
  
  
  return {
  	// summary:
  	//		TODOC
  	constrainedMoveable: constrainedMoveable,
  	boxConstrainedMoveable: boxConstrainedMoveable,
  	parentConstrainedMoveable: parentConstrainedMoveable
  };
  
  });
  