(function(global, _, $) {

  var Miso = global.Miso = (global.Miso || {});

  Miso.Engine = function( config ) {
    this._buildTransitions( config.transitions );
    this._buildScenes( config.scenes || {} );
    this.current = config.initial || 'initial';
    this.lastTransition = 'none';
  }

  _.extend(Miso.Engine.prototype, {
    error : function() {
    },

    transition : function( transitionName ) {
      var transition = this.transitions[transitionName],
          complete = _.Deferred();

      //Can't fire a transition that isn't defined
      if (!transition) {
        throw "Transition '" + transitionName + "' not found!"
      }
      
      //we in the middle of a transition?
      if (this._transitioning) { 
        return complete.reject();
      }

      //if it's not a legit transition, reject it
      if ( transition.cant(this.current) ) {
        return complete.reject(); 
      }

      this._transitioning = true;
      var from = this.current,
          to = transition.to,
          toScene = this.scenes[to],
          fromScene = this.scenes[from],
          lastTransition = this.lastTransition,
          afterComplete = _.Deferred(),
          beforeComplete = _.Deferred(),
          introComplete = _.Deferred(),
          outroComplete = _.Deferred();
          args = Array.prototype.slice.call(arguments, 1);

      //run the from.after and to.before checks in order
      (lastTransition && lastTransition.after) ? lastTransition.after(afterComplete, fromScene, args) : afterComplete.resolve();
      _.when(afterComplete).then(function() {
        transition.before ? transition.before(beforeComplete, toScene, args) : beforeComplete.resolve();
      });

      //Once before and after have run....
      _.when(afterComplete, beforeComplete)

        //If our before or after fails, bail out here.
        .fail(_.bind(function() {
          console.log('failed!');
          this._transitioning = false;
          complete.reject();
        }, this))

        //Run our intro and outro in order
        .then(function() {
          _.when(outroComplete).then(function() {
            transition.intro ? transition.intro(introComplete, toScene, args) : introComplete.resolve();
          });
          (lastTransition && lastTransition.outro) ? lastTransition.outro(outroComplete, fromScene, args) : outroComplete.resolve();
        });
        
      //all events done, let's tidy up
      _.when(afterComplete, beforeComplete, introComplete, outroComplete).then(_.bind(function() {
        this.lastTransition = transition;
        this.current = transition.to;
        this._transitioning = false;
        console.log('complete!', this.current, this.lastTransition);
        complete.resolve();
      }, this));
      return complete;
    },

    state : function() {
      return this.current;
    },

    is : function( state ) {
      return (state === this.current);
    },

    inTransition : function() {
      return (this._transitioning === true);
    },

    _buildTransitions : function( transitions ) {
      this.transitions = {};
      _.each(transitions, function(originalTransition) {
        var transition;
        if (transition instanceof Miso.Transition) {
          transition = originalTransition;
        } else {
          transition = new Miso.Transition(originalTransition);
        }
        this.transitions[transition.name] = transition.attach(this);
      }, this);
    },

    _buildScenes : function( scenes ) {
      this.scenes = {};
      _.each(this.transitions, function(t) {
        this.scenes[t.to] = (scenes[t.to] || {});
      }, this);

    }

  });

}(this, _, $));

@@ -277,17 +277,8 @@
 tion
- = 'none'
 ;%0A  
@@ -1424,32 +1424,8 @@
 tion
- && lastTransition.after
 ) ? 
@@ -1561,28 +1561,8 @@
     
- transition.before ?
  tra
@@ -1610,35 +1610,8 @@
 rgs)
- : beforeComplete.resolve()
 ;%0A  
@@ -1800,42 +1800,8 @@
 ) %7B%0A
-          console.log('failed!');%0A
     
@@ -2018,27 +2018,8 @@
     
- transition.intro ?
  tra
@@ -2065,34 +2065,8 @@
 rgs)
- : introComplete.resolve()
 ;%0A  
@@ -2083,25 +2083,24 @@
 ;%0A          
-(
 lastTransiti
@@ -2105,33 +2105,8 @@
 tion
- && lastTransition.outro)
  ? l
@@ -2464,77 +2464,8 @@
 se;%0A
-        console.log('complete!', this.current, this.lastTransition);%0A
     

refactor of core transition logic to take into account assumption of handler existance