         return true if parent.isBusy()
     false
 
+  ### 
+  Node instances call this function when done activating. If there is a pending action it will be executed.
+  @param [Node] node
+  ###
   @onNodeActivated: (node)->
     node.parent().onChildActivated(node) if node.parent()
     if action = node.onActivatedAction()
       @processAction action
 
+  ### 
+  Node instances call this function when done deactivating. If there is a pending action it will be executed.
+  @param [Node] node
+  ###
   @onNodeDeactivated: (node)->
     node.parent().onChildDeactivated(node) if node.parent()
     if action = node.onDeactivatedAction()

        @beforeDeactivate()
        @doDeactivate()

    @onChildIdUpdated = (oldId, newId, child)->
      delete __childMap[oldId]
      __childMap[newId] = child

    @setOnActivatedAction = (action) ->
      onActivatedAction = action

    @onActivatedAction = ->
      onActivatedAction

    @setOnDeactivatedAction = (action) ->
      onDeactivatedAction = action

    @onDeactivatedAction = ->
      onDeactivatedAction

    # Refactor the options into a common getter?
    @childrenCanActivate = ->
      childrenCanActivate

    @setMode = (m) ->
      mode = m

    @mode = () ->
      mode

    @setParent = (node) ->
      parent = node

    @parent = ->
      parent

    @childrenAsArray = (obj) ->
      arr = []
      for id, child of __childMap
        arr.push child
      return arr

    @addChild = (node) ->

      throw new Error(
        "ExoReferenceError -> addChild: #{node} is not a valid Exo.Node"
      ) if node == null or typeof node == 'undefined'

      throw new Error(
        "ExoReferenceError -> An Exo.Node instance can't pass itself to addChild"
      ) if @nodeId() == node.nodeId()

      node.setParent(@)
      __childMap[node.nodeId()] = node

    @removeChild = (node) ->
      delete __childMap[node.nodeId()]

    @setDefaultChild = (node) ->
      __defaultChild = node

    @defaultChild = ->
      __defaultChild

    @children = ->
      @childrenAsArray()

    @activatedChildren = ->
      @children().filter (n) -> n.isActivated()

    @childById = (id) ->
      __childMap[id]

    @descendantById = (id) ->
      child = @childById(id)
      if child
        return child

      for child in children
        descendant = child.getDescendantById(id)
        if descendant
          return descendant

    @siblings = () ->
      ownId = @nodeId()

      if parent
        return parent.children().filter (n)-> n.nodeId() isnt ownId

      return []

    @isActivated = ->
      @sm().currentState() == Node.States.ACTIVATED

    @isTransitioning = ->
      @sm().isTransitioning()

    @isBusy = ->
      return true if @isTransitioning()

      if @mode() == Node.Modes.EXCLUSIVE
        # Why was this in here? It didn't work.. check old implementation!
        # return true if @onActivatedAction() != null or @onDeactivatedAction() != null
        return true if @children().filter((n) -> n.isBusy()).length > 0

      return false

    @haveBusyChildren = ->
      @children().filter((n) -> n.isBusy()).length > 0

    @attemptTransition = (t) ->
      @sm().attemptTransition t

    @activate = -> Node.activate @
    @deactivate = -> Node.deactivate @
    @toggle = -> Node.toggle @

    # TODO
    @deactivateChildren = ->
      for child in @children()
        child.deactivate()

    @onActivated = ->
      @sm().onTransitionComplete()
      Node.onNodeActivated @
      @setOnActivatedAction null

    @onDeactivated = ->
      @sm().onTransitionComplete()
      Node.onNodeDeactivated @
      @setOnDeactivatedAction null

  beforeActivate: ->
  doActivate: -> @onActivated()

    EXCLUSIVE: 'exclusive'
    MULTI: 'multi'

  ### 
  Generate the next unique node ID string.
  ###
  @nextId: ->
    Node.__currentId = Node.__currentId + 1

    return Node.__currentId

  ### 
  Attempt to activate a node instance.
  @param [Node] node
  ###
  @activate: (node) ->
    return false if @lineageIsBusy(node) or node.isActivated()

