define(function () {
	var allow, disallow, undef;

	allow = true;
	disallow = false;

	/**
	 * This strategy defers all update events (property change events) until
	 * the node currently being edited leaves the editing state (edit:false).
	 * The converse of this strategy is RevertPropertyChangesAtRollback.
	 */
	// TODO: propagate property changes when finished editing
	return function createStrategy () {
		var nodeBeingEdited;

		return {

			allowEvent: function (isOn, type, sourceNode, allNodes) {
				if (nodeBeingEdited) {
					if (type == 'edit') {
						if (isOn) {
							// don't allow another node to enter editing state
							return disallow;
						}
						else if (nodeBeingEdited == sourceNode) {
							// node is leaving editing state
							nodeBeingEdited = undef;
							return allow;
						}
						else {
							// TODO: throw if we get an isOn==false from a node that isn't being edited?
							return disallow;
						}
					}
					else {
						// disallow select while editing
						return type == 'set' ? disallow : allow;
					}
				}
				else {
					if (type == 'edit' && isOn) {
						nodeBeingEdited = sourceNode;
					}
					return allow;
				}
			},

			processEvent: undef

		};

	};

});