<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>LICENSE</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -37,9 +37,10 @@
 		&lt;cfloop condition=&quot;transitions.hasNext()&quot;&gt;
 			&lt;cfset transition = transitions.next() /&gt;
 			&lt;cfif transition.perform(obj)&gt;
-				&lt;cfbreak /&gt;
+				&lt;cfreturn true /&gt;
 			&lt;/cfif&gt;
-		&lt;/cfloop&gt;		
+		&lt;/cfloop&gt;	
+		&lt;cfreturn false /&gt;	
 	&lt;/cffunction&gt;	
 	
 	&lt;cffunction name=&quot;transitions&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;</diff>
      <filename>Event.cfc</filename>
    </modified>
    <modified>
      <diff>@@ -10,51 +10,35 @@
 		&lt;cfreturn this /&gt;
 	&lt;/cffunction&gt;
 	
-	&lt;!--- Set up chainable callback handlers ---&gt;
-	
-	&lt;cffunction name=&quot;setEnterCallback&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
-		&lt;cfargument name=&quot;method&quot; type=&quot;string&quot; required=&quot;true&quot; /&gt;			
-		&lt;cfset instance.callbacks.enter = arguments.method /&gt;
-		&lt;cfreturn this /&gt;
-	&lt;/cffunction&gt;
-	
-	&lt;cffunction name=&quot;setAfterCallback&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
-		&lt;cfargument name=&quot;method&quot; type=&quot;string&quot; required=&quot;true&quot; /&gt;			
-		&lt;cfset instance.callbacks.after = arguments.method /&gt;
-		&lt;cfreturn this /&gt;
-	&lt;/cffunction&gt;
-	
-	&lt;cffunction name=&quot;setExitCallback&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
-		&lt;cfargument name=&quot;method&quot; type=&quot;string&quot; required=&quot;true&quot; /&gt;			
-		&lt;cfset instance.callbacks.exit = arguments.method /&gt;
-		&lt;cfreturn this /&gt;
-	&lt;/cffunction&gt;
-	
 	&lt;cffunction name=&quot;getName&quot; returntype=&quot;string&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
 		&lt;cfreturn instance.name /&gt;
 	&lt;/cffunction&gt;
 	
-	&lt;cffunction name=&quot;entering&quot; returntype=&quot;void&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
+	&lt;cffunction name=&quot;before&quot; returntype=&quot;boolean&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
 		&lt;cfargument name=&quot;obj&quot; required=&quot;true&quot; /&gt;
-		&lt;cfset invokeCallback('#getName()#EnteringAction', arguments.obj) /&gt;
+		&lt;cfreturn invokeCallback('before#getName()#Action', arguments.obj) /&gt;
 	&lt;/cffunction&gt;
 	
-	&lt;cffunction name=&quot;entered&quot; returntype=&quot;void&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
+	&lt;cffunction name=&quot;after&quot; returntype=&quot;void&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
 		&lt;cfargument name=&quot;obj&quot; required=&quot;true&quot; /&gt;
-		&lt;cfset invokeCallback('#getName()#AfterAction', arguments.obj) /&gt;
+		&lt;cfset invokeCallback('after#getName()#Action', arguments.obj) /&gt;
 	&lt;/cffunction&gt;	
 	
-	&lt;cffunction name=&quot;exited&quot; returntype=&quot;void&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
+	&lt;cffunction name=&quot;exit&quot; returntype=&quot;void&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
 		&lt;cfargument name=&quot;obj&quot; required=&quot;true&quot; /&gt;
-		&lt;cfset invokeCallback('#getName()#ExitAction', arguments.obj) /&gt;
+		&lt;cfset invokeCallback('exit#getName()#Action', arguments.obj) /&gt;
 	&lt;/cffunction&gt;
 	
-	&lt;cffunction name=&quot;invokeCallback&quot; returntype=&quot;void&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
+	&lt;cffunction name=&quot;invokeCallback&quot; returntype=&quot;boolean&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
 		&lt;cfargument name=&quot;callback&quot; type=&quot;string&quot; required=&quot;true&quot; /&gt;
-		&lt;cfargument name=&quot;obj&quot; required=&quot;true&quot; /&gt;		
+		&lt;cfargument name=&quot;obj&quot; required=&quot;true&quot; /&gt;
 		&lt;cfif structKeyExists(arguments.obj, arguments.callback)&gt;
-			&lt;cfinvoke component=&quot;#arguments.obj#&quot; method=&quot;#arguments.callback#&quot; /&gt;
+			&lt;cfinvoke component=&quot;#arguments.obj#&quot; method=&quot;#arguments.callback#&quot; returnvariable=&quot;result&quot; /&gt;
+			&lt;cfif isDefined('result') and isBoolean(result)&gt;
+				&lt;cfreturn result /&gt;
+			&lt;/cfif&gt; 
 		&lt;/cfif&gt;
+		&lt;cfreturn true /&gt;
 	&lt;/cffunction&gt;
 
 &lt;/cfcomponent&gt;
\ No newline at end of file</diff>
      <filename>State.cfc</filename>
    </modified>
    <modified>
      <diff>@@ -83,9 +83,9 @@
 		&lt;cfargument name=&quot;stateName&quot; required=&quot;true&quot; /&gt;
 		&lt;cfscript&gt;
 			var state = instance.states[arguments.stateName];
-			state.entering(this);
+			state.before(this);
 			setState(arguments.stateName);
-			state.entered(this);
+			state.after(this);
 		&lt;/cfscript&gt;
 	&lt;/cffunction&gt;
 	</diff>
      <filename>StateMachine.cfc</filename>
    </modified>
    <modified>
      <diff>@@ -39,22 +39,23 @@
 		&lt;cfscript&gt;
 			var local = structNew();
 		
-			if(not guard(obj)) return false;
+			if(not guard(obj)) {
+				return false;
+			}
 		
 			local.isLoopback = obj.getCurrentState() eq getToState();
 			local.states = arguments.obj.getStates();
 			local.nextState = local.states[getToState()];
 			local.oldState = local.states[obj.getCurrentState()];
 			
-			if(not local.isLoopback) { 
-				local.nextState.entering(obj);	
-			}
-			
-			obj.setState(getToState());
-			
-			if(not local.isLoopback) { 
-				local.nextState.entered(obj);	
-				local.oldState.exited(obj);	
+			if(not local.isLoopback) {
+				if(local.nextState.before(obj)) {	
+					obj.setState(getToState());
+					local.nextState.after(obj);	
+					local.oldState.exit(obj);	
+				} else {
+				 return false;
+				}
 			}
 			
 			return true;</diff>
      <filename>StateTransition.cfc</filename>
    </modified>
    <modified>
      <diff>@@ -13,6 +13,7 @@
 			addState('read');
 			addState('closed');
 			addState('awaitingResponse');
+			addState('filed');
 			addState('junk');
 
 			addEvent('newMessage').addTransitions('read,closed,awaitingResponse', 'needingAttention');
@@ -21,33 +22,39 @@
 			addEvent('close').addTransitions('read,awaitingResponse', 'closed', 'getCanClose').addTransitions('read,awaitingResponse', 'read', 'alwaysTrue');
 			addEvent('junk').addTransitions('read,closed,awaitingResponse', 'junk');
 			addEvent('unjunk').addTransitions('junk', 'closed');
+			addEvent('file').addTransitions('read,closed,awaitingResponse', 'filed');
 		&lt;/cfscript&gt;
 	&lt;/cffunction&gt;
 	
 	&lt;!--- State Observer Events ---&gt;
 	
-	&lt;cffunction name=&quot;readEnteringAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
+	&lt;cffunction name=&quot;beforeReadAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
 		&lt;cfset getOriginalObject().setReadEnter(true) /&gt;
 	&lt;/cffunction&gt;
 
-	&lt;cffunction name=&quot;readExitAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
+	&lt;cffunction name=&quot;beforeFiledAction&quot; access=&quot;public&quot; returntype=&quot;boolean&quot; output=&quot;false&quot;&gt;
+		&lt;!--- Let's assume this event checked for the existence of a folder and failed  ---&gt;
+		&lt;cfreturn false /&gt;
+	&lt;/cffunction&gt;
+	
+	&lt;cffunction name=&quot;exitReadAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
 		&lt;cfset getOriginalObject().setReadExit(true) /&gt;
 	&lt;/cffunction&gt;
 	
-	&lt;cffunction name=&quot;readAfterAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
+	&lt;cffunction name=&quot;afterReadAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
 		&lt;cfset getOriginalObject().setReadAfterFirstAction(true) /&gt;
 		&lt;cfset getOriginalObject().setReadAfterSecondAction(true) /&gt;
 	&lt;/cffunction&gt;
 
-	&lt;cffunction name=&quot;needingAttentionEnteringAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
+	&lt;cffunction name=&quot;beforeNeedingAttentionAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
 		&lt;cfset getOriginalObject().setNeedingAttentionEnter(true) /&gt;
 	&lt;/cffunction&gt;
 	
-	&lt;cffunction name=&quot;needingAttentionAfterAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
+	&lt;cffunction name=&quot;afterNeedingAttentionAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
 		&lt;cfset getOriginalObject().setNeedingAttentionAfter(true) /&gt;
 	&lt;/cffunction&gt;
 
-	&lt;cffunction name=&quot;closedAfterAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
+	&lt;cffunction name=&quot;afterClosedAction&quot; access=&quot;public&quot; returntype=&quot;void&quot; output=&quot;false&quot;&gt;
 		&lt;cfset getOriginalObject().setClosedAfter(true) /&gt;
 	&lt;/cffunction&gt;
 </diff>
      <filename>test/ConversationState.cfc</filename>
    </modified>
    <modified>
      <diff>@@ -112,7 +112,7 @@
 			assertTrue(conversation.getReadEnter());
 		&lt;/cfscript&gt;
 	&lt;/cffunction&gt;	
-	
+
 	&lt;cffunction name=&quot;testAfterActionsExecuted&quot; returntype=&quot;void&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
 		&lt;cfscript&gt;
 			conversation.setReadAfterFirstAction(false);
@@ -193,5 +193,23 @@
 			assertTrue(conversation.isJunk());
 		&lt;/cfscript&gt;
 	&lt;/cffunction&gt;
+
+	&lt;cffunction name=&quot;testTransitionAbortedIfBeforeActionReturnsFalse&quot; returntype=&quot;void&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
+		&lt;cfscript&gt;
+			assertTrue(conversation.view());
+			assertTrue(conversation.isRead());
+			assertFalse(conversation.file());
+			assertTrue(conversation.isRead());
+		&lt;/cfscript&gt;
+	&lt;/cffunction&gt;	
+	
+	&lt;cffunction name=&quot;testEventReturnsTrueWhenTransitionIsSuccessful&quot; returntype=&quot;void&quot; access=&quot;public&quot; output=&quot;false&quot;&gt;
+		&lt;cfscript&gt;
+			assertFalse(conversation.junk());
+			assertTrue(conversation.view());
+		&lt;/cfscript&gt;
+	&lt;/cffunction&gt;
+
+
 	
 &lt;/cfcomponent&gt;
\ No newline at end of file</diff>
      <filename>test/StateMachineTest.cfc</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>b336ed32deeb1f7a7410b1ad692e363d88624a07</id>
    </parent>
  </parents>
  <author>
    <name>Ryan Wood</name>
    <email>ryan.wood@gmail.com</email>
  </author>
  <url>http://github.com/ryanwood/shade/commit/94ee712cb48348cfe764d06a9181405bfb125a95</url>
  <id>94ee712cb48348cfe764d06a9181405bfb125a95</id>
  <committed-date>2008-07-18T12:11:38-07:00</committed-date>
  <authored-date>2008-07-18T12:11:38-07:00</authored-date>
  <message>Added License. Changed 'entering' callback to 'before'. Events now return a boolean value as to their success. Before callback will halt the transition if false. [#1 state:resolved]</message>
  <tree>f8fcfd4417fe161a7a9f9867cee834091c073a3b</tree>
  <committer>
    <name>Ryan Wood</name>
    <email>ryan.wood@gmail.com</email>
  </committer>
</commit>
