Use prototypes instead of this directly

Use prototypes instead of this directly

    q     = require 'q'
    fs    = require 'fs'
    async = require 'async'
    uuid  = require 'uuid-1345'

    microtime = require 'microtime'

    EventEmitter2 = require('eventemitter2').EventEmitter2
    emitter       = new EventEmitter2 wildcard: true

    available   = { }
    initialized = { }
    listeners   = { }

    underscore = (value) -> value.replace /\W+/g, '_'
    strip      = (name)  -> name.toLowerCase().replace /\W+/g, ''

    SEARCH_ROOTS  = { }
    WRAPPED       = { }
    _INITIALIZERS = { }
    HYDRATED      = { }
    LOCALS        = { }

    HYRDATION_LISTENERS = { }

    INITIALIZERS = (cls, method) ->
      _INITIALIZERS[cls] = [ ] unless _INITIALIZERS[cls]?

      _INITIALIZERS[cls].push fn: method, called: false

    WRAP = (cls, method) ->
      unless WRAPPED[cls]?
        WRAPPED[cls] = [
          'constructor'
          'initialize'
          'details'
        ]

      WRAPPED[cls].indexOf(method) < 0

    class Madul

      details: =>
        name  = @.__proto__.constructor.name
        props = for own key, val of @.__proto__
          if key != 'constructor' &&
             key != 'details'     &&
             key != 'initialize'  && ((
               key[0]            == '_' &&
               @.__proto__[key]? == false
             ) || key[0] != '_')

            if typeof val == 'function'
              value = val.constructor.name
            else if Array.isArray val
              value = for v in val
                if typeof v == 'function'
                  v.constructor.name
                else if typeof v == 'object'
                  v.constructor.name
                else
                  v
              value = value.join ','
            else if typeof val == 'object'
              value = val.constructor.name
            else
              value = val

            "#{key} => #{value}"

        "\n  #{name}\n    #{props.filter((e) -> e?).join '\n    '}"

      @LISTEN: (event, callback) => emitter.on event, callback

      @FIRE: (event, args) => emitter.emit event, args

      @SEARCH_ROOT: (mod, path) =>
        Madul.FIRE '$.Madul.search_root.register', "#{mod}": path

        SEARCH_ROOTS[mod] = path.substring 0, path.lastIndexOf '/'

      @PARSE_SPEC: (value) =>
        tokens = value.split '='

        if tokens.length == 2
          initer = tokens[1].trim()
          t      = tokens[0].split '->'

          if t[0].indexOf('#') > -1
            r = t[0].split '#'

            root = r[0].trim()
            t[0] = r[1]

          if t.length == 2
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = n.substring 1, n.length
            else
              local = false
              name  = n

            alias = t[1].trim()
          else if t.length == 1
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = alias = n.substring 1, n.length
            else
              local = false
              name  = alias = n
          else
            return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

          toks = initer.split ':'

          if toks.length == 2
            initer = toks[0].trim()
            pres   = toks[1].split(',').map (p) => p.trim()
          else if toks.length == 1
            initer = toks[0].trim()
          else
            return Madul.FIRE '!.Madul.dependency_spec.initializer.invalid', tokens[1]

        else if tokens.length == 1
          t = tokens[0].split '->'

          if t[0].indexOf('#') > -1
            r = t[0].split '#'

            root = r[0].trim()
            t[0] = r[1]

          if t.length == 2
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = n.substring 1, n.length
            else
              local = false
              name  = n

            alias = t[1].trim()
          else if t.length == 1
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = alias = n.substring 1, n.length
            else
              local = false
              name  = alias = n
          else
            return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

        else
          return Madul.FIRE '!.Madul.dependency_spec.invalid', d

        { ref: alias || name, alias, name, root, initer, pres, local }

      @BUILD_SPEC: ({ search_root, name, alias, initializer, prerequisites }) =>
        unless name?
          return Madul.FIRE '!.Madul.dependency_spec.name-required', arguments[0]

        if prerequisites? && initializer? == false
          return Madul.FIRE '!.Madul.dependency_spec.prerequisites-require-initializer', arguments[0]

        "#{if search_root?   then "#{search_root}#"            else ''}\
         #{name}\
         #{if alias?         then " -> #{alias}"               else ''}\
         #{if initializer?   then " = #{initializer}"          else ''}\
         #{if prerequisites? then ":#{prerequisites.join ','}" else ''}\
        "

      listen: (event, callback) ->
        Madul.LISTEN "*.#{@constructor.name}.#{event}", callback

      fire: (event, args) ->
        Madul.FIRE "@.#{@constructor.name}.#{event}", args

      warn: (event, details) ->
        Madul.FIRE "!.#{@constructor.name}.#{event}", details

      _report: (name, method, state, id, args) =>
        if state == 'reject'
          Madul.FIRE "!.#{name}.#{method}.#{state}",
            uuid:      id
            message:   args
            timestamp: microtime.now()
        else
          Madul.FIRE "@.#{name}.#{method}.#{state}",
            uuid:      id
            args:      args
            timestamp: microtime.now()

      _respond: (proto, method, id, deferred) =>
        (state, data) =>
          process.nextTick =>
            deferred[state] data

            proto._report proto.constructor.name, method, state, id, data

      _prep_invocation: (proto, method, input, def) =>
        id  = uuid.v4fast()
        res = proto._respond proto, method, id, def

        if Array.isArray input
          input.push (out) => res 'resolve', out
          input.push (err) => res 'reject',  err
          input.push (out) => res 'notify',  out
        else if typeof input == 'object'
          input.done   = (out) => res 'resolve', out
          input.fail   = (err) => res 'reject',  err
          input.update = (out) => res 'notify',  out

          input = [ input ]
        else
          msg = "input to #{proto.constructor.name}.#{method} must be an Array of Object"
          proto.warn.call proto, 'input.invalid', msg
          throw new Error msg

        proto._report proto.constructor.name, method, 'invoke', id, input

        input

      _do_wrap: (proto, method) =>
        if method != 'fire' && method != 'warn' && method != 'listen'
          Madul.FIRE "$.#{proto.constructor.name}.#{method}.wrap"

          if typeof proto[method] == 'function'
            proto["_#{method}"] = proto[method]

            proto[method] = =>
              def  = q.defer()
              args = Array.prototype.slice.call arguments

              proto["_#{method}"].apply proto, proto._prep_invocation proto, method, args, def

              def.promise
          else if typeof proto[method] == 'object'

            if Array.isArray proto[method].validate
              args_format = 'ARRAY'
              decs        = proto[method].validate

              proto[method].validate = decs
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = for own key, val of proto[method].validate
                val
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ proto[method].validate ]
            else if typeof proto[method].validate != 'undefined'
              proto.warn.call proto, 'meta.invalid', validate: 'must be a String, Object, or Array'
              return
            else
              args_format = 'ARRAY'
              decs        = [ ]

            if Array.isArray proto[method].before
              decs = decs.concat proto[method].before
            else if typeof proto[method].before == 'string'
              decs = decs.concat [ proto[method].before ]

            if Array.isArray proto[method].after
              decs = decs.concat proto[method].after
            else if typeof proto[method].after == 'string'
              decs = decs.concat [ Madul.PARSE_SPEC proto[method].after ]

            Madul.FIRE '$.Madul.decorators.hydrate', decs

            @_do_hydrate proto, decs, =>
              proto["_#{method}"] = proto[method]

              proto[method] = =>
                def = q.defer()
                me  = proto["_#{method}"]

                if args_format == 'ARRAY'
                  args = Array.prototype.slice.call arguments

                  if me.validate?
                    validators = for val, i in me.validate
                      { ref } = Madul.PARSE_SPEC val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[i]
                      proto[ref].EXECUTE.call proto[ref], args[i]
                else if args_format == 'OBJECT'
                  args = arguments[0]

                  if me.validate?
                    validators = for own key, val of me.validate
                      { ref } = Madul.PARSE_SPEC val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[key]
                      proto[ref].EXECUTE.call proto[ref], args[key]
                else
                  proto.warn.call proto, 'cannot-continue', 'No arg format specified'

                  return def.reject 'No arg format specified'

                if Array.isArray me.before
                  before = me.before.map (b) => Madul.PARSE_SPEC(b).ref
                else if typeof me.before == 'string'
                  before = [ Madul.PARSE_SPEC(me.before).ref ]
                else
                  before = [ ]

                if Array.isArray me.after
                  after = me.after.map (a) => Madul.PARSE_SPEC(a).ref
                else if typeof me.after == 'string'
                  after = [ Madul.PARSE_SPEC(me.after).ref ]
                else
                  after = [ ]

                q.all validators
                .then =>
                  q.all before.map (b) =>
                    Madul.FIRE '$.Madul.before_filter.execute', "#{b}": args
                    proto[b].before.call proto[b], args
                .then =>
                  me.behavior.apply me, @_prep_invocation proto, method, args, def
                .then (result) =>
                  if after.length > 0
                    q.all after.map (a) =>
                      Madul.FIRE '$.Madul.after_filter.execute', "#{a}": result
                      proto[a].after.call proto[a], result
                  else
                    d = q.defer()

                    process.nextTick => d.resolve result

                    d.promise
                .then  (out) => def.resolve out
                .catch (err) => def.reject  err

                def.promise
          else
            proto.warn.call proto, 'cannot-wrap', method

          WRAPPED[proto.constructor.name].push method

      _wrap_methods: (proto, callback) =>
        name    = proto.constructor.name
        to_wrap = [ ]

        while proto? && Object.keys(proto).length > 0 && WRAPPED[name]? == false
          to_wrap.push { proto, name, methods: [ ] }

          for own prop, body of proto
            if prop[0]                  != '_'         &&
               typeof proto["_#{prop}"] == 'undefined' &&
               WRAP(name, prop)         == true

              continue if proto.deps? && proto.deps.indexOf(prop.replace(/_/g, '-')) > -1

              if typeof body == 'function' || typeof body?.behavior == 'function'
                to_wrap[to_wrap.length - 1].methods.push prop

          proto = proto.__proto__
          name  = proto.constructor.name

        async.each to_wrap.reverse(), (wrap, completed) =>
          async.each wrap.methods, (method, next) =>
            wrap.proto._do_wrap wrap.proto, method

            INITIALIZERS wrap.name, method if method[0] == '$'

            next()
          , => @_call_initializers_for wrap.proto, wrap.name, completed
        , callback

      _make_available: (name, mod) =>
        Madul.FIRE "$.#{name}.available"

        available[strip name] = mod

      _hydrate_deps: (proto, done) =>
        protos = [ proto ]

        if proto.__proto__?
          while proto.__proto__? && Object.keys(proto.__proto__).length > 0
            protos.push proto = proto.__proto__

        async.each protos.reverse(), (p, next) =>
          name = p.constructor.name

          if p.hasOwnProperty 'deps'
            if HYDRATED[name] == undefined
              HYDRATED[name]            = false
              HYRDATION_LISTENERS[name] = [ next ]

              p._do_hydrate p, p.deps, =>
                HYDRATED[name] = true

                for listener in HYRDATION_LISTENERS[name]
                  listener()
            else if HYDRATED[name] == false
              HYRDATION_LISTENERS[name].push next
            else if HYDRATED[name] == true
              next()
          else
            next()
        , done

      _init_if_madul: (path, callback) =>
        mod      = require path
        proto    = mod
        is_madul = false

        while proto
          is_madul = true if proto.name == 'Madul'
          if is_madul                            == false      &&
             proto.constructor.name              != 'Object'   &&
             typeof proto                        == 'function' &&
             typeof proto.__super__?.constructor == 'function'
            proto = proto.__super__.constructor
          else
            proto = undefined

        if is_madul
          new mod()
            .initialize()
            .then callback
        else
          callback mod

      _load: (me, name, path, loaded) =>
        me._init_if_madul path, (mod) =>
          me._make_available name, mod
          loaded mod

      _check: (me, path, dep, ref, finished) =>
        fs.readdir path, (err, files) =>
          if err?
            me.warn 'file-not-found', err

            done type: 'ERROR', info: err
          else
            async.each files, (f, next) =>
              depth = "#{path}/#{f}"

              fs.stat depth, (e, s) =>
                if s.isDirectory() && f[0] != '.'
                  me._check me, depth, dep, ref, next
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  me._load me, ref, depth, (mod) => me._do_add me, mod, ref, next
                else
                  next()
            , finished

      _do_add: (me, mod, ref, next) =>
        Madul.FIRE "$.#{me.constructor.name}.dependency.register", ref

        me[underscore ref] = mod

        next()

      _add: (me, ref, path, next) =>
        me._init_if_madul path, (mod) =>
          me._make_available ref, mod
          me._do_add me, mod, ref, next

      _do_hydrate: (proto, deps, hydration_complete) =>
        initers = [ ]

        async.each deps, (d, next) =>
          { ref, alias, name, root, initer, pres, local } = Madul.PARSE_SPEC d

          if pres?
            insert_at = for p in pres
              index_for = (sibling) => sibling.alias == p.alias

              initers.find index_for

            insert_at.sort()

            insert_at = if insert_at.length == 0 then 0 else insert_at[insert_at.length - 1]

            initers.splice insert_at, 0, alias: alias, execute: initer

          if proto[underscore ref]? == false
            if available[strip ref]? == true
              proto._do_add proto, available[strip ref], ref, next
            else
              if root?
                Madul.FIRE '$.Madul.search_root.load', { name, alias, root }

                @_do_hydrate proto, [ root ], =>
                  if SEARCH_ROOTS[root] == undefined
                    SEARCH_ROOTS[root] = @_find_code_root root

                  proto._check proto, SEARCH_ROOTS[root], name, ref, next
              else if local
                proto._check proto, LOCALS[proto.constructor.name], name, ref, next
              else
                try
                  proto._add proto, ref, name, next
                catch e
                  cwd = process.cwd()
                  pkg = "#{cwd}/node_modules/#{name}/package.json"

                  fs.stat pkg, (err, stat) =>
                    if stat?.isFile()
                      fs.readFile pkg, 'utf8', (err, data) =>
                        json = JSON.parse data
                        main = json.main || json._main || 'index.js'
                        path = "#{cwd}/node_modules/#{name}/#{main}"

                        proto._add proto, ref, path, next
                    else
                      proto._check proto, LOCALS[proto.constructor.name], name, ref, next
          else
            next()
        , =>
          async.eachSeries initers, (initer, next) =>
            proto[initer.execute].apply(@).then next
          , hydration_complete

      _finish_up: (proto, args) =>
        name = proto.constructor.name

        if listeners[name]?
          async.each listeners[name], (listener, next) =>
            listener @
            next()
          , => @_register_initialized name
        else
          @_register_initialized name

      _register_initialized: (name) =>
        @_make_available name, @

        initialized[name] = true

        Madul.FIRE "$.#{name}.initialized"

      _call_initializers_for: (proto, name, callback) =>
        if _INITIALIZERS[name]?
          async.each _INITIALIZERS[name], (initializer, next) =>
            if initializer.called == false
              proto[initializer.fn].apply proto
                .then =>
                  initializer.called = true
                  next()
            else
              next()
          , callback
        else
          callback()

      _find_code_root: (resource) =>
        file  = resource.toLowerCase()
        found = for own key, val of require.cache
          if key.replace(/_/g, '').toLowerCase().includes file
            key.substring(0, key.lastIndexOf '/').split '/'

        found
          .filter (f) => f?
          .sort((a, b) => a.length - b.length)[0]
          .join '/'

      initialize: =>
        deferred = q.defer()
        proto    = @.__proto__
        name     = proto.constructor.name

        Madul.FIRE "$.#{name}.request_instance"

        if initialized[name] == undefined
          Madul.FIRE "$.#{name}.initialize"

          initialized[name] = false
          listeners[name]   = [ deferred.resolve ]

          if LOCALS[name] == undefined
            LOCALS[name] = @_find_code_root name

          @_hydrate_deps proto, => @_wrap_methods proto, => @_finish_up proto
        else if initialized[name] == false
          listeners[name].push deferred.resolve
        else if initialized[name] == true
          process.nextTick => deferred.resolve available[strip name]

        deferred.promise

    module.exports = Madul

    q     = require 'q'
    fs    = require 'fs'
    async = require 'async'
    uuid  = require 'uuid-1345'

    microtime = require 'microtime'

    EventEmitter2 = require('eventemitter2').EventEmitter2
    emitter       = new EventEmitter2 wildcard: true

    available   = { }
    initialized = { }
    listeners   = { }

    underscore = (value) -> value.replace /\W+/g, '_'
    strip      = (name)  -> name.toLowerCase().replace /\W+/g, ''

    SEARCH_ROOTS  = { }
    WRAPPED       = { }
    _INITIALIZERS = { }
    HYDRATED      = { }
    LOCALS        = { }

    HYRDATION_LISTENERS = { }

    INITIALIZERS = (cls, method) ->
      _INITIALIZERS[cls] = [ ] unless _INITIALIZERS[cls]?

      _INITIALIZERS[cls].push fn: method, called: false

    WRAP = (cls, method) ->
      unless WRAPPED[cls]?
        WRAPPED[cls] = [
          'constructor'
          'initialize'
          'details'
        ]

      WRAPPED[cls].indexOf(method) < 0

    class Madul

      details: =>
        name  = @.__proto__.constructor.name
        props = for own key, val of @.__proto__
          if key != 'constructor' &&
             key != 'details'     &&
             key != 'initialize'  && ((
               key[0]            == '_' &&
               @.__proto__[key]? == false
             ) || key[0] != '_')

            if typeof val == 'function'
              value = val.constructor.name
            else if Array.isArray val
              value = for v in val
                if typeof v == 'function'
                  v.constructor.name
                else if typeof v == 'object'
                  v.constructor.name
                else
                  v
              value = value.join ','
            else if typeof val == 'object'
              value = val.constructor.name
            else
              value = val

            "#{key} => #{value}"

        "\n  #{name}\n    #{props.filter((e) -> e?).join '\n    '}"

      @LISTEN: (event, callback) => emitter.on event, callback

      @FIRE: (event, args) => emitter.emit event, args

      @SEARCH_ROOT: (mod, path) =>
        Madul.FIRE '$.Madul.search_root.register', "#{mod}": path

        SEARCH_ROOTS[mod] = path.substring 0, path.lastIndexOf '/'

      @PARSE_SPEC: (value) =>
        tokens = value.split '='

        if tokens.length == 2
          initer = tokens[1].trim()
          t      = tokens[0].split '->'

          if t[0].indexOf('#') > -1
            r = t[0].split '#'

            root = r[0].trim()
            t[0] = r[1]

          if t.length == 2
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = n.substring 1, n.length
            else
              local = false
              name  = n

            alias = t[1].trim()
          else if t.length == 1
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = alias = n.substring 1, n.length
            else
              local = false
              name  = alias = n
          else
            return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

          toks = initer.split ':'

          if toks.length == 2
            initer = toks[0].trim()
            pres   = toks[1].split(',').map (p) => p.trim()
          else if toks.length == 1
            initer = toks[0].trim()
          else
            return Madul.FIRE '!.Madul.dependency_spec.initializer.invalid', tokens[1]

        else if tokens.length == 1
          t = tokens[0].split '->'

          if t[0].indexOf('#') > -1
            r = t[0].split '#'

            root = r[0].trim()
            t[0] = r[1]

          if t.length == 2
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = n.substring 1, n.length
            else
              local = false
              name  = n

            alias = t[1].trim()
          else if t.length == 1
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = alias = n.substring 1, n.length
            else
              local = false
              name  = alias = n
          else
            return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

        else
          return Madul.FIRE '!.Madul.dependency_spec.invalid', d

        { ref: alias || name, alias, name, root, initer, pres, local }

      @BUILD_SPEC: ({ search_root, name, alias, initializer, prerequisites }) =>
        unless name?
          return Madul.FIRE '!.Madul.dependency_spec.name-required', arguments[0]

        if prerequisites? && initializer? == false
          return Madul.FIRE '!.Madul.dependency_spec.prerequisites-require-initializer', arguments[0]

        "#{if search_root?   then "#{search_root}#"            else ''}\
         #{name}\
         #{if alias?         then " -> #{alias}"               else ''}\
         #{if initializer?   then " = #{initializer}"          else ''}\
         #{if prerequisites? then ":#{prerequisites.join ','}" else ''}\
        "

      listen: (event, callback) ->
        Madul.LISTEN "*.#{@constructor.name}.#{event}", callback

      fire: (event, args) ->
        Madul.FIRE "@.#{@constructor.name}.#{event}", args

      warn: (event, details) ->
        Madul.FIRE "!.#{@constructor.name}.#{event}", details

      _report: (name, method, state, id, args) =>
        if state == 'reject'
          Madul.FIRE "!.#{name}.#{method}.#{state}",
            uuid:      id
            message:   args
            timestamp: microtime.now()
        else
          Madul.FIRE "@.#{name}.#{method}.#{state}",
            uuid:      id
            args:      args
            timestamp: microtime.now()

      _respond: (proto, method, id, deferred) =>
        (state, data) =>
          process.nextTick =>
            deferred[state] data

            proto._report proto.constructor.name, method, state, id, data

      _prep_invocation: (proto, method, input, def) =>
        id  = uuid.v4fast()
        res = proto._respond proto, method, id, def

        if Array.isArray input
          input.push (out) => res 'resolve', out
          input.push (err) => res 'reject',  err
          input.push (out) => res 'notify',  out
        else if typeof input == 'object'
          input.done   = (out) => res 'resolve', out
          input.fail   = (err) => res 'reject',  err
          input.update = (out) => res 'notify',  out

          input = [ input ]
        else
          msg = "input to #{proto.constructor.name}.#{method} must be an Array of Object"
          @warn 'input.invalid', msg
          throw new Error msg

        proto._report proto.constructor.name, method, 'invoke', id, input

        input

      _do_wrap: (proto, method) =>
        if method != 'fire' && method != 'warn' && method != 'listen'
          Madul.FIRE "$.#{proto.constructor.name}.#{method}.wrap"

          if typeof proto[method] == 'function'
            proto["_#{method}"] = proto[method]

            proto[method] = =>
              def  = q.defer()
              args = Array.prototype.slice.call arguments

              proto["_#{method}"].apply proto, proto._prep_invocation proto, method, args, def

              def.promise
          else if typeof proto[method] == 'object'

            if Array.isArray proto[method].validate
              args_format = 'ARRAY'
              decs        = proto[method].validate

              proto[method].validate = decs
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = for own key, val of proto[method].validate
                val
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ proto[method].validate ]
            else if typeof proto[method].validate != 'undefined'
              proto.warn.call proto, 'meta.invalid', validate: 'must be a String, Object, or Array'
              return
            else
              args_format = 'ARRAY'
              decs        = [ ]

            if Array.isArray proto[method].before
              decs = decs.concat proto[method].before
            else if typeof proto[method].before == 'string'
              decs = decs.concat [ proto[method].before ]

            if Array.isArray proto[method].after
              decs = decs.concat proto[method].after
            else if typeof proto[method].after == 'string'
              decs = decs.concat [ Madul.PARSE_SPEC proto[method].after ]

            Madul.FIRE '$.Madul.decorators.hydrate', decs

            @_do_hydrate proto, decs, =>
              proto["_#{method}"] = proto[method]

              proto[method] = =>
                def = q.defer()
                me  = proto["_#{method}"]

                if args_format == 'ARRAY'
                  args = Array.prototype.slice.call arguments

                  if me.validate?
                    validators = for val, i in me.validate
                      { ref } = Madul.PARSE_SPEC val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[i]
                      proto[ref].EXECUTE.call proto[ref], args[i]
                else if args_format == 'OBJECT'
                  args = arguments[0]

                  if me.validate?
                    validators = for own key, val of me.validate
                      { ref } = Madul.PARSE_SPEC val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[key]
                      proto[ref].EXECUTE.call proto[ref], args[key]
                else
                  proto.warn.call proto, 'cannot-continue', 'No arg format specified'

                  return def.reject 'No arg format specified'

                if Array.isArray me.before
                  before = me.before.map (b) => Madul.PARSE_SPEC(b).ref
                else if typeof me.before == 'string'
                  before = [ Madul.PARSE_SPEC(me.before).ref ]
                else
                  before = [ ]

                if Array.isArray me.after
                  after = me.after.map (a) => Madul.PARSE_SPEC(a).ref
                else if typeof me.after == 'string'
                  after = [ Madul.PARSE_SPEC(me.after).ref ]
                else
                  after = [ ]

                q.all validators
                .then =>
                  q.all before.map (b) =>
                    Madul.FIRE '$.Madul.before_filter.execute', "#{b}": args
                    proto[b].before.call proto[b], args
                .then =>
                  me.behavior.apply me, @_prep_invocation proto, method, args, def
                .then (result) =>
                  if after.length > 0
                    q.all after.map (a) =>
                      Madul.FIRE '$.Madul.after_filter.execute', "#{a}": result
                      proto[a].after.call proto[a], result
                  else
                    d = q.defer()

                    process.nextTick => d.resolve result

                    d.promise
                .then  (out) => def.resolve out
                .catch (err) => def.reject  err

                def.promise
          else
            @warn 'cannot-wrap', method

          WRAPPED[proto.constructor.name].push method

      _wrap_methods: (proto, callback) =>
        name    = proto.constructor.name
        to_wrap = [ ]

        while proto? && Object.keys(proto).length > 0 && WRAPPED[name]? == false
          to_wrap.push { proto, name, methods: [ ] }

          for own prop, body of proto
            if prop[0]                  != '_'         &&
               typeof proto["_#{prop}"] == 'undefined' &&
               WRAP(name, prop)         == true

              continue if proto.deps? && proto.deps.indexOf(prop.replace(/_/g, '-')) > -1

              if typeof body == 'function' || typeof body?.behavior == 'function'
                to_wrap[to_wrap.length - 1].methods.push prop

          proto = proto.__proto__
          name  = proto.constructor.name

        async.each to_wrap.reverse(), (wrap, completed) =>
          async.each wrap.methods, (method, next) =>
            wrap.proto._do_wrap wrap.proto, method

            INITIALIZERS wrap.name, method if method[0] == '$'

            next()
          , => @_call_initializers_for wrap.proto, wrap.name, completed
        , callback

      _make_available: (name, mod) =>
        Madul.FIRE "$.#{name}.available"

        available[strip name] = mod

      _hydrate_deps: (proto, done) =>
        protos = [ proto ]

        if proto.__proto__?
          while proto.__proto__? && Object.keys(proto.__proto__).length > 0
            protos.push proto = proto.__proto__

        async.each protos.reverse(), (p, next) =>
          name = p.constructor.name

          if p.hasOwnProperty 'deps'
            if HYDRATED[name] == undefined
              HYDRATED[name]            = false
              HYRDATION_LISTENERS[name] = [ next ]

              p._do_hydrate p, p.deps, =>
                HYDRATED[name] = true

                for listener in HYRDATION_LISTENERS[name]
                  listener()
            else if HYDRATED[name] == false
              HYRDATION_LISTENERS[name].push next
            else if HYDRATED[name] == true
              next()
          else
            next()
        , done

      _init_if_madul: (path, callback) =>
        mod      = require path
        proto    = mod
        is_madul = false

        while proto
          is_madul = true if proto.name == 'Madul'
          if is_madul                            == false      &&
             proto.constructor.name              != 'Object'   &&
             typeof proto                        == 'function' &&
             typeof proto.__super__?.constructor == 'function'
            proto = proto.__super__.constructor
          else
            proto = undefined

        if is_madul
          new mod()
            .initialize()
            .then callback
        else
          callback mod

      _load: (me, name, path, loaded) =>
        me._init_if_madul path, (mod) =>
          me._make_available name, mod
          loaded mod

      _check: (me, path, dep, ref, finished) =>
        fs.readdir path, (err, files) =>
          if err?
            me.warn 'file-not-found', err

            done type: 'ERROR', info: err
          else
            async.each files, (f, next) =>
              depth = "#{path}/#{f}"

              fs.stat depth, (e, s) =>
                if s.isDirectory() && f[0] != '.'
                  me._check me, depth, dep, ref, next
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  me._load me, ref, depth, (mod) => me._do_add me, mod, ref, next
                else
                  next()
            , finished

      _do_add: (me, mod, ref, next) =>
        Madul.FIRE "$.#{me.constructor.name}.dependency.register", ref

        me[underscore ref] = mod

        next()

      _add: (me, ref, path, next) =>
        me._init_if_madul path, (mod) =>
          me._make_available ref, mod
          me._do_add me, mod, ref, next

      _do_hydrate: (proto, deps, hydration_complete) =>
        initers = [ ]

        async.each deps, (d, next) =>
          { ref, alias, name, root, initer, pres, local } = Madul.PARSE_SPEC d

          if pres?
            insert_at = for p in pres
              index_for = (sibling) => sibling.alias == p.alias

              initers.find index_for

            insert_at.sort()

            insert_at = if insert_at.length == 0 then 0 else insert_at[insert_at.length - 1]

            initers.splice insert_at, 0, alias: alias, execute: initer

          if proto[underscore ref]? == false
            if available[strip ref]? == true
              proto._do_add proto, available[strip ref], ref, next
            else
              if root?
                Madul.FIRE '$.Madul.search_root.load', { name, alias, root }

                @_do_hydrate proto, [ root ], =>
                  if SEARCH_ROOTS[root] == undefined
                    SEARCH_ROOTS[root] = @_find_code_root root

                  proto._check proto, SEARCH_ROOTS[root], name, ref, next
              else if local
                proto._check proto, LOCALS[proto.constructor.name], name, ref, next
              else
                try
                  proto._add proto, ref, name, next
                catch e
                  cwd = process.cwd()
                  pkg = "#{cwd}/node_modules/#{name}/package.json"

                  fs.stat pkg, (err, stat) =>
                    if stat?.isFile()
                      fs.readFile pkg, 'utf8', (err, data) =>
                        json = JSON.parse data
                        main = json.main || json._main || 'index.js'
                        path = "#{cwd}/node_modules/#{name}/#{main}"

                        proto._add proto, ref, path, next
                    else
                      proto._check proto, LOCALS[proto.constructor.name], name, ref, next
          else
            next()
        , =>
          async.eachSeries initers, (initer, next) =>
            proto[initer.execute].apply(@).then next
          , hydration_complete

      _finish_up: (proto, args) =>
        name = proto.constructor.name

        if listeners[name]?
          async.each listeners[name], (listener, next) =>
            listener @
            next()
          , => @_register_initialized name
        else
          @_register_initialized name

      _register_initialized: (name) =>
        @_make_available name, @

        initialized[name] = true

        Madul.FIRE "$.#{name}.initialized"

      _call_initializers_for: (proto, name, callback) =>
        if _INITIALIZERS[name]?
          async.each _INITIALIZERS[name], (initializer, next) =>
            if initializer.called == false
              proto[initializer.fn].apply @
                .then =>
                  initializer.called = true
                  next()
            else
              next()
          , callback
        else
          callback()

      _find_code_root: (resource) =>
        file  = resource.toLowerCase()
        found = for own key, val of require.cache
          if key.replace(/_/g, '').toLowerCase().includes file
            key.substring(0, key.lastIndexOf '/').split '/'

        found
          .filter (f) => f?
          .sort((a, b) => a.length - b.length)[0]
          .join '/'

      initialize: =>
        deferred = q.defer()
        proto    = @.__proto__
        name     = proto.constructor.name

        Madul.FIRE "$.#{name}.request_instance"

        if initialized[name] == undefined
          Madul.FIRE "$.#{name}.initialize"

          initialized[name] = false
          listeners[name]   = [ deferred.resolve ]

          if LOCALS[name] == undefined
            LOCALS[name] = @_find_code_root name

          @_hydrate_deps proto, => @_wrap_methods proto, => @_finish_up proto
        else if initialized[name] == false
          listeners[name].push deferred.resolve
        else if initialized[name] == true
          process.nextTick => deferred.resolve available[strip name]

        deferred.promise

    module.exports = Madul


fix issue during list item removal. properly handle rpc/action execution context binding to 'kProp'. skip trying to chain binding with function/action content for now

# Property - controller of Object properties

The `Property` class is the *secretive shadowy* element that governs
`Object` behavior and are bound to the `Object` via
`Object.defineProperty`. It acts like a shadow `Proxy/Reflector` to
the `Object` instance and provides tight control via the
`Getter/Setter` interfaces.

The `Property` instances attach themselves to the `Object[Symbol.for('property')]` property
and are rarely accessed directly - but they are the **fundamental**
actors that *actualize* YANG schema compliance into ordinary JS
objects.

Below are list of properties available to every instance of `Property`:

property | type | mapping | description
--- | --- | --- | ---
name   | string | direct | name of the property
schema | object | direct | a schema instance (usually [Yang](./src/yang.listcoffee))
state  | object | direct | *private* object holding internal state
container | object | access(state) | reference to object containing this property
configurable | boolean | getter(state) | defines whether this property can be redefined
enumerable   | boolean | getter(state) | defines whether this property is enumerable
content | any | computed | getter/setter for `state.value`
context | object | computed | dynamically generated using [context](./src/context.coffee)
root  | [Property](./src/property.litcoffee) | computed | dynamically returns the root Property instance
props | array(Property) | computed | returns children Property instances
key   | string/number | computed | conditionally returns unique key for Property if a list item
path  | [XPath](./src/xpath.coffee) | computed | dynamically generate XPath for this Property from root

## Class Property

    debug    = require('debug')('yang:property') # if process.env.DEBUG?
    co       = require 'co'
    delegate = require 'delegates'
    clone    = require 'clone'
    Emitter  = require('events').EventEmitter
    context  = require './context'
    XPath    = require './xpath'
    kProp    = Symbol.for('property')

    class Property

      @property: (prop, desc) ->
        Object.defineProperty @prototype, prop, desc

      constructor: (@name, @schema={}) ->
        unless this instanceof Property then return new Property arguments...

        @state =
          value: null
          container: null
          configurable: true
          enumerable: @binding?
          mutable: @schema.config?.valueOf() isnt false
        Object.setPrototypeOf @state, Emitter.prototype

        @schema.kind ?= 'anydata'

        # Bind the get/set functions to call with 'this' bound to this
        # Property instance.  This is needed since native Object
        # Getter/Setter uses the Object itself as 'this'
        @set = @set.bind this
        @get = @get.bind this
        # expose the BoundThis for the set/get
        @set.bound = @get.bound = this

        # soft freeze this instance
        Object.preventExtensions this

      delegate @prototype, 'state'
        .method 'once'
        .method 'on'
        .access 'container'
        .getter 'configurable'
        .getter 'enumerable'
        .getter 'mutable'

      delegate @prototype, 'schema'
        .getter 'kind'
        .getter 'type'
        .getter 'binding'

### Computed Properties

      @property 'content',
        get: -> @state.value
        set: (value) -> @set value, force: true

      @property 'context',
        get: ->
          ctx = Object.create(context)
          ctx.state = {}
          ctx.property = this
          Object.preventExtensions ctx
          return ctx

      @property 'parent', get: -> @container?[kProp]

      @property 'root',
        get: ->
          return this if @kind is 'module'
          root = switch
            when @parent is this then this
            when @parent instanceof Property then @parent.root
            else this
          @state.path = undefined unless @state.root is root
          return @state.root = root

      @property 'children',
        get: ->
          return [] unless @content instanceof Object
          children = []
          for own k of Object.keys(@content)
            desc = Object.getOwnPropertyDescriptor(@content, k)
            children.push desc.get.bound if desc?.get?.bound instanceof Property
          return children

      @property 'key',
        get: ->
          return unless @schema is @parent?.schema
          switch
            when @content not instanceof Object  then @name + 1
            when @content.hasOwnProperty('@key') then @content['@key']
            when Array.isArray @container
              for idx, item of @container when item is @content
                idx = Number(idx) unless (Number.isNaN (Number idx))
                return idx+1
              return undefined

      @property 'path',
        get: ->
          if this is @root
            entity = switch
              when @kind is 'module' then '/'
              else '.'
            return XPath.parse entity, @schema
          key = @key
          return @state.path if @state.path? and not key?
          @debug "[path] #{@kind}(#{@name}) has #{key} #{typeof key}"
          entity = switch typeof key
            when 'number' then ".[#{key}]"
            when 'string' then ".[key('#{key}')]"
            else switch
              when @kind is 'list' then @schema.datakey
              else @name
          @debug "[path] #{@parent.name} + #{entity}"
          return @state.path = @parent.path.clone().append entity

## Instance-level methods

      clone: ->
        @debug "[clone] cloning with #{@children.length} properties"
        copy = (new @constructor @name, @schema)
        copy.state[k] = v for k, v of @state
        return copy

      emit: (event) ->
        @state.emit arguments...
        unless this is @root
          @debug "[emit] '#{event}' to '#{@root.name}'"
          @root.emit arguments...

### join (obj)

This call is the primary mechanism via which the `Property` instance
attaches itself to the provided target `obj`. It defines itself in the
target `obj` via `Object.defineProperty`.

      join: (obj, opts={ replace: false, suppress: false, force: false }) ->
        return obj unless obj instanceof Object

        detached = true unless @container?
        @container = obj

        if Array.isArray(obj) and Array.isArray(@content)
          @debug @content
          throw @error "cannot join array property into list container"
        if @kind is 'list' and not Array.isArray(obj) and @content? and not Array.isArray(@content)
          throw @error "cannot join non-list array property into containing object"

        # if joining for the first time, apply existing data unless explicit replace
        exists = obj[@name]
        if detached and opts.replace isnt true
          @debug "[join] applying existing data for #{@name} to:"
          @debug obj
          opts.suppress = true
          @set exists, opts

        # TODO: should produce meaningful warning?
        try Object.defineProperty obj, @name, this
        @debug "[join] attached into #{obj.constructor.name} container"
        return obj

### get (pattern)

This is the main `Getter` for the target object's property value. When
called with optional `pattern` it will perform an internal
[find](#find-xpath) operation to traverse/locate that value being
requested instead of returning its own `@content`.

It also provides special handling based on different types of
`@content` currently held.

When `@content` is a function, it will call it with the current
`@context` instance as the bound context for the function being
called.

      get: (pattern, prop=false) -> switch
        when pattern? and prop then @in pattern
        when pattern?
          match = @find pattern
          switch
            when match.length is 1 then match[0].content
            when match.length > 1  then match.map (x) -> x.content
            else undefined
        when @kind in [ 'rpc', 'action' ] then switch
          when @binding? then @do.bind this
          else @content
        else
          if @binding? and not (@kind is 'list' and @key?)
            try return @binding.call @context
            catch e
              throw @error "issue executing registered function binding during get(): #{e.message}", e
          @content

### set (value)

This is the main `Setter` for the target object's property value.  It
utilizes internal `@schema` attribute if available to enforce schema
validations.

      set: (value, opts={ force: false, suppress: false }) ->
        @debug "[set] enter with:"
        @debug value
        #@debug opts
        return this if value is @content and not opts.force
        unless @mutable or not value? or opts.force
          throw @error "cannot set data on read-only element"

        try
          unless value instanceof Function
            if value[kProp] instanceof Property and value[kProp] isnt this
              @debug "[set] cloning existing property for assignment"
              value = clone(value)
            value = Object.create(value) unless Object.isExtensible(value)
          Object.defineProperty value, kProp, configurable: true, value: this

        value = switch
          when @schema.apply?
            @schema.apply value, @context.with(opts)
          else value
        return this if value instanceof Error
        try
          Object.defineProperty value, kProp, value: this
          Object.defineProperty value, '$', value: @get.bind(this)
          if @schema.nodes.length and @kind isnt 'module'
            for own k of value
              desc = Object.getOwnPropertyDescriptor value, k
              if desc.writable is true and not @schema.locate(k)?
                @debug "[set] hiding non-schema defined property: #{k}"
                Object.defineProperty value, k, enumerable: false

        @state.prev = @state.value
        @state.enumerable = value? or @binding?

        if @binding?.length is 1 and not opts.force and @kind not in [ 'action', 'rpc' ]
          try @binding.call @context, value
          catch e
            throw @error "issue executing registered function binding during set(): #{e.message}", e
        else
          @state.value = value

        try Object.defineProperty @container, @name,
          configurable: true
          enumerable: @state.enumerable

        @emit 'update', this if this is @root or not opts.suppress
        @debug "[set] completed"
        return this

### merge (value)

Performs a granular merge of `value` into existing `@content` if
available, otherwise performs [set](#set-value) operation.

      merge: (value, opts={ replace: true, suppress: false }) ->
        opts.replace ?= true
        unless @content instanceof Object
          opts.replace = false
          return @set value, opts

        value = value[@name] if value? and value.hasOwnProperty @name
        return this unless value instanceof Object

        if Array.isArray @content
          length = @content.length
          @debug "[merge] merging into existing Array(#{length}) for #{@name}"
          @debug value
          # here we clone this Property and update with only the newly merged values
          # XXX - this logic needs refinement, it doesn't handle min-elements condition properly
          value = [ value ] unless Array.isArray value
          copy = @clone()
          copy.set value, force: opts.force, suppress: true
          @debug "[merge] combining and applying schema"
          if @schema.key? and opts.replace
            exists = {}
            @content.forEach (item) ->
              key = item['@key']
              exists[key] = item
            @debug "[merge] reducing existing keys"
            conflicts = 0
            newitems = copy.content.reduce ((a, item) ->
              key = item['@key']
              item[kProp].name -= conflicts
              if key of exists
                conflicts++
                exists[key][kProp].merge item
              else
                a.push item
              return a
            ), []
            combine = @content.concat newitems
          else
            newitems = copy.content
            combine = @content.concat newitems
          attr.apply combine for attr in @schema.attrs
          newitems.forEach (item) =>
            item[kProp].name += length
            item[kProp].join @content, opts
          @emit 'update', this unless opts.suppress
          return copy
        else
          @debug "[merge] merging into existing Object(#{Object.keys(@content).length}) for #{@name}"
          # TODO: protect this as a transaction?
          @content[k] = v for own k, v of value when @content.hasOwnProperty k
          # TODO: need to reapply schema to self
          return this

### create (value)

A simple convenience wrap around the above [merge](#merge-value) operation.

      create: (value) ->
        if not @content? and @kind is 'list' and not Array.isArray value
          value = [ value ]
        res = @merge value, replace: false
        @emit 'create', res
        return res

### remove

The reverse of [join](#join-obj), it will detach itself from the
`@container` parent object.

      remove: ->
        return this unless @container?
        if @key?
          #@container.splice @name, 1
          delete @container[@name]
        else
          @state.enumerable = false
          @state.value = undefined unless @kind is 'list'
          Object.defineProperty @container, @name, enumerable: false
        @emit 'update', @parent if @parent?
        @emit 'delete', this
        return this

### find (pattern)

This helper routine can be used to allow traversal to other elements
in the data tree from the relative location of the current `Property`
instance. It returns matching `Property` instances based on the
provided `pattern` in the form of XPATH or YPATH.

It is internally used via [get](#get) and generally used inside
controller logic bound inside the [Yang expression](./yang.litcoffee)
as well as event handler listening on [Model](./model.litcoffee)
events.

It *always* returns an array (empty to denote no match) unless it
encounters an error, in which case it will throw an Error.

      find: (pattern='.', opts={}) ->
        @debug "[find] #{pattern}"
        unless pattern instanceof XPath
          if /^\.\.\//.test(pattern) and @parent?
            return @parent.find pattern.replace(/^\.\.\//, ''), opts
          if /^\//.test(pattern) and this isnt @root
            return @root.find pattern, opts
          pattern = XPath.parse pattern, @schema

        @debug "[find] using #{pattern}"
        if opts.root or not @container? or pattern.tag not in [ '/', '..' ]
          @debug "[find] apply #{pattern}"
          @debug @content
          pattern.apply(@content).props ? []
        else switch
          when pattern.tag is '/'  and @parent? then @parent.find pattern, opts
          when pattern.tag is '..' and @parent? then @parent.find pattern.xpath, opts
          else []

### in (pattern)

A convenience routine to locate one or more matching Property
instances based on `pattern` (XPATH or YPATH) from this Model.

      in: (pattern) ->
        try props = @find pattern
        return unless props? and props.length
        return switch
          when props.length > 1 then props
          else props[0]

### do ()

A convenience wrap to a Property instance that holds a function to
perform a Promise-based execution.

Always returns a Promise.

      invoke: ->
        console.warn "DEPRECATION: please use .do() instead"
        @do arguments...

      do: ->
        unless (@binding instanceof Function) or (@content instanceof Function)
          return Promise.reject @error "cannot perform action on a property without function"
        try
          @debug "[do] executing method: #{@name}"
          ctx = @context
          ctx.state[kProp] = this
          @schema.input?.eval  ctx.state, {}
          @schema.output?.eval ctx.state, {}
          ctx.input = arguments
          # first apply schema bound function (if availble), then
          # execute assigned function (if available and not 'missing')
          if @binding?
            @debug "[do] calling bound function"
            @debug @binding.toString()
            res = @binding.apply ctx, arguments
            ctx.output ?= res
          else
            @debug "[do] calling assigned function: #{@content.name}"
            @debug @content.toString()
            ctx.output = @content.apply @container, arguments
          return co =>
            @debug "[do] evaluating output schema"
            ctx.output = yield Promise.resolve ctx.output
            @debug "[do] finish setting output"
            @emit 'done', ctx
            return ctx.output
        catch e
          @debug e
          return Promise.reject e

### error (msg)

Provides more contextual error message pertaining to the Property instance.

      error: (msg, ctx=this) ->
        at = "#{@path}"
        at += @name if at is '/'
        res = new Error "[#{at}] #{msg}"
        res.name = 'PropertyError'
        res.context = ctx
        return res

      debug: (msg) ->
        if debug? then switch typeof msg
          when 'object' then debug msg
          else
            node = this
            prefix = [ @name ]
            prefix.unshift node.name while (node = node.parent)
            debug "[#{prefix.join('/')}] #{msg}"

### inspect

      inspect: ->
        return {
          name:   @schema.tag ? @name
          kind:   @schema.kind
          key:    @key
          xpath:  @path.toString()
          schema: @schema.toJSON tag: false, extended: true
          active: @enumerable
          readonly: not @mutable
        }

### toJSON

This call creates a new copy of the current `Property.content`
completely detached/unbound to the underlying data schema. It's main
utility is to represent the current data state for subsequent
serialization/transmission. It accepts optional argument `tag` which
when called with `false` will not tag the produced object with the
current property's `@name`.

      toJSON: (tag=true) ->
        copy = (src) ->
          return unless src? and typeof src isnt 'function'
          if typeof src is 'object'
            try res = new src.constructor
            catch then res = {}
            for own k, v of src when typeof v isnt 'function'
              res[k] = copy v
            return res
          src.constructor.call src, src
        value = copy @get()
        value ?= [] if @kind is 'list'
        if tag
          name = switch
            when @kind is 'list' then @schema.datakey
            else @name
          "#{name}": value
        else value

## Export Property Class

    module.exports = Property

# Property - controller of Object properties

The `Property` class is the *secretive shadowy* element that governs
`Object` behavior and are bound to the `Object` via
`Object.defineProperty`. It acts like a shadow `Proxy/Reflector` to
the `Object` instance and provides tight control via the
`Getter/Setter` interfaces.

The `Property` instances attach themselves to the `Object[Symbol.for('property')]` property
and are rarely accessed directly - but they are the **fundamental**
actors that *actualize* YANG schema compliance into ordinary JS
objects.

Below are list of properties available to every instance of `Property`:

property | type | mapping | description
--- | --- | --- | ---
name   | string | direct | name of the property
schema | object | direct | a schema instance (usually [Yang](./src/yang.listcoffee))
state  | object | direct | *private* object holding internal state
container | object | access(state) | reference to object containing this property
configurable | boolean | getter(state) | defines whether this property can be redefined
enumerable   | boolean | getter(state) | defines whether this property is enumerable
content | any | computed | getter/setter for `state.value`
context | object | computed | dynamically generated using [context](./src/context.coffee)
root  | [Property](./src/property.litcoffee) | computed | dynamically returns the root Property instance
props | array(Property) | computed | returns children Property instances
key   | string/number | computed | conditionally returns unique key for Property if a list item
path  | [XPath](./src/xpath.coffee) | computed | dynamically generate XPath for this Property from root

## Class Property

    debug    = require('debug')('yang:property') # if process.env.DEBUG?
    co       = require 'co'
    delegate = require 'delegates'
    clone    = require 'clone'
    Emitter  = require('events').EventEmitter
    context  = require './context'
    XPath    = require './xpath'
    kProp    = Symbol.for('property')

    class Property

      @property: (prop, desc) ->
        Object.defineProperty @prototype, prop, desc

      constructor: (@name, @schema={}) ->
        unless this instanceof Property then return new Property arguments...

        @state =
          value: null
          container: null
          configurable: true
          enumerable: @binding?
          mutable: @schema.config?.valueOf() isnt false
        Object.setPrototypeOf @state, Emitter.prototype

        @schema.kind ?= 'anydata'

        # Bind the get/set functions to call with 'this' bound to this
        # Property instance.  This is needed since native Object
        # Getter/Setter uses the Object itself as 'this'
        @set = @set.bind this
        @get = @get.bind this
        # expose the BoundThis for the set/get
        @set.bound = @get.bound = this

        # soft freeze this instance
        Object.preventExtensions this

      delegate @prototype, 'state'
        .method 'once'
        .method 'on'
        .access 'container'
        .getter 'configurable'
        .getter 'enumerable'
        .getter 'mutable'

      delegate @prototype, 'schema'
        .getter 'kind'
        .getter 'type'
        .getter 'binding'

### Computed Properties

      @property 'content',
        get: -> @state.value
        set: (value) -> @set value, force: true

      @property 'context',
        get: ->
          ctx = Object.create(context)
          ctx.state = {}
          ctx.property = this
          Object.preventExtensions ctx
          return ctx

      @property 'parent', get: -> @container?[kProp]

      @property 'root',
        get: ->
          return this if @kind is 'module'
          root = switch
            when @parent is this then this
            when @parent instanceof Property then @parent.root
            else this
          @state.path = undefined unless @state.root is root
          return @state.root = root

      @property 'children',
        get: ->
          return [] unless @content instanceof Object
          children = []
          for own k of Object.keys(@content)
            desc = Object.getOwnPropertyDescriptor(@content, k)
            children.push desc.get.bound if desc?.get?.bound instanceof Property
          return children

      @property 'key',
        get: ->
          return unless @schema is @parent?.schema
          switch
            when @content not instanceof Object  then @name + 1
            when @content.hasOwnProperty('@key') then @content['@key']
            when Array.isArray @container
              for idx, item of @container when item is @content
                idx = Number(idx) unless (Number.isNaN (Number idx))
                return idx+1
              return undefined

      @property 'path',
        get: ->
          if this is @root
            entity = switch
              when @kind is 'module' then '/'
              else '.'
            return XPath.parse entity, @schema
          key = @key
          return @state.path if @state.path? and not key?
          @debug "[path] #{@kind}(#{@name}) has #{key} #{typeof key}"
          entity = switch typeof key
            when 'number' then ".[#{key}]"
            when 'string' then ".[key('#{key}')]"
            else switch
              when @kind is 'list' then @schema.datakey
              else @name
          @debug "[path] #{@parent.name} + #{entity}"
          return @state.path = @parent.path.clone().append entity

## Instance-level methods

      clone: ->
        @debug "[clone] cloning with #{@children.length} properties"
        copy = (new @constructor @name, @schema)
        copy.state[k] = v for k, v of @state
        return copy

      emit: (event) ->
        @state.emit arguments...
        unless this is @root
          @debug "[emit] '#{event}' to '#{@root.name}'"
          @root.emit arguments...

### join (obj)

This call is the primary mechanism via which the `Property` instance
attaches itself to the provided target `obj`. It defines itself in the
target `obj` via `Object.defineProperty`.

      join: (obj, opts={ replace: false, suppress: false, force: false }) ->
        return obj unless obj instanceof Object

        detached = true unless @container?
        @container = obj

        if Array.isArray(obj) and Array.isArray(@content)
          @debug @content
          throw @error "cannot join array property into list container"
        if @kind is 'list' and not Array.isArray(obj) and @content? and not Array.isArray(@content)
          throw @error "cannot join non-list array property into containing object"

        # if joining for the first time, apply existing data unless explicit replace
        exists = obj[@name]
        if detached and opts.replace isnt true
          @debug "[join] applying existing data for #{@name} to:"
          @debug obj
          opts.suppress = true
          @set exists, opts

        # TODO: should produce meaningful warning?
        try Object.defineProperty obj, @name, this
        @debug "[join] attached into #{obj.constructor.name} container"
        return obj

### get (pattern)

This is the main `Getter` for the target object's property value. When
called with optional `pattern` it will perform an internal
[find](#find-xpath) operation to traverse/locate that value being
requested instead of returning its own `@content`.

It also provides special handling based on different types of
`@content` currently held.

When `@content` is a function, it will call it with the current
`@context` instance as the bound context for the function being
called.

      get: (pattern, prop=false) -> switch
        when pattern? and prop then @in pattern
        when pattern?
          match = @find pattern
          switch
            when match.length is 1 then match[0].content
            when match.length > 1  then match.map (x) -> x.content
            else undefined
        when @kind in [ 'rpc', 'action' ] then switch
          when @binding? then @do.bind this
          else @content
        else
          if @binding? and not (@kind is 'list' and @key?)
            try return @binding.call @context
            catch e
              throw @error "issue executing registered function binding during get(): #{e.message}", e
          @content

### set (value)

This is the main `Setter` for the target object's property value.  It
utilizes internal `@schema` attribute if available to enforce schema
validations.

      set: (value, opts={ force: false, suppress: false }) ->
        @debug "[set] enter with:"
        @debug value
        #@debug opts
        return this if value is @content and not opts.force
        unless @mutable or not value? or opts.force
          throw @error "cannot set data on read-only element"

        try
          unless value instanceof Function
            if value[kProp] instanceof Property and value[kProp] isnt this
              @debug "[set] cloning existing property for assignment"
              value = clone(value)
            value = Object.create(value) unless Object.isExtensible(value)
          Object.defineProperty value, kProp, configurable: true, value: this

        value = switch
          when @schema.apply?
            @schema.apply value, @context.with(opts)
          else value
        return this if value instanceof Error
        try
          Object.defineProperty value, kProp, value: this
          Object.defineProperty value, '$', value: @get.bind(this)
          if @schema.nodes.length and @kind isnt 'module'
            for own k of value
              desc = Object.getOwnPropertyDescriptor value, k
              if desc.writable is true and not @schema.locate(k)?
                @debug "[set] hiding non-schema defined property: #{k}"
                Object.defineProperty value, k, enumerable: false

        @state.prev = @state.value
        @state.enumerable = value? or @binding?

        if @binding?.length is 1 and not opts.force and @kind not in [ 'action', 'rpc' ]
          try @binding.call @context, value
          catch e
            throw @error "issue executing registered function binding during set(): #{e.message}", e
        else
          @state.value = value

        try Object.defineProperty @container, @name,
          configurable: true
          enumerable: @state.enumerable

        @emit 'update', this if this is @root or not opts.suppress
        @debug "[set] completed"
        return this

### merge (value)

Performs a granular merge of `value` into existing `@content` if
available, otherwise performs [set](#set-value) operation.

      merge: (value, opts={ replace: true, suppress: false }) ->
        opts.replace ?= true
        unless @content instanceof Object
          opts.replace = false
          return @set value, opts

        value = value[@name] if value? and value.hasOwnProperty @name
        return this unless value instanceof Object

        if Array.isArray @content
          length = @content.length
          @debug "[merge] merging into existing Array(#{length}) for #{@name}"
          @debug value
          # here we clone this Property and update with only the newly merged values
          # XXX - this logic needs refinement, it doesn't handle min-elements condition properly
          value = [ value ] unless Array.isArray value
          copy = @clone()
          copy.set value, force: opts.force, suppress: true
          @debug "[merge] combining and applying schema"
          if @schema.key? and opts.replace
            exists = {}
            @content.forEach (item) ->
              key = item['@key']
              exists[key] = item
            @debug "[merge] reducing existing keys"
            conflicts = 0
            newitems = copy.content.reduce ((a, item) ->
              key = item['@key']
              item[kProp].name -= conflicts
              if key of exists
                conflicts++
                exists[key][kProp].merge item
              else
                a.push item
              return a
            ), []
            combine = @content.concat newitems
          else
            newitems = copy.content
            combine = @content.concat newitems
          attr.apply combine for attr in @schema.attrs
          newitems.forEach (item) =>
            item[kProp].name += length
            item[kProp].join @content, opts
          @emit 'update', this unless opts.suppress
          return copy
        else
          @debug "[merge] merging into existing Object(#{Object.keys(@content).length}) for #{@name}"
          # TODO: protect this as a transaction?
          @content[k] = v for own k, v of value when @content.hasOwnProperty k
          # TODO: need to reapply schema to self
          return this

### create (value)

A simple convenience wrap around the above [merge](#merge-value) operation.

      create: (value) ->
        if not @content? and @kind is 'list' and not Array.isArray value
          value = [ value ]
        res = @merge value, replace: false
        @emit 'create', res
        return res

### remove

The reverse of [join](#join-obj), it will detach itself from the
`@container` parent object.

      remove: ->
        return this unless @container?
        if @key?
          @container.splice @name, 1
          #delete @parent[@name]
        else
          @state.enumerable = false
          @state.value = undefined unless @kind is 'list'
          Object.defineProperty @container, @name, enumerable: false
        @emit 'update', @parent if @parent?
        @emit 'delete', this
        return this

### find (pattern)

This helper routine can be used to allow traversal to other elements
in the data tree from the relative location of the current `Property`
instance. It returns matching `Property` instances based on the
provided `pattern` in the form of XPATH or YPATH.

It is internally used via [get](#get) and generally used inside
controller logic bound inside the [Yang expression](./yang.litcoffee)
as well as event handler listening on [Model](./model.litcoffee)
events.

It *always* returns an array (empty to denote no match) unless it
encounters an error, in which case it will throw an Error.

      find: (pattern='.', opts={}) ->
        @debug "[find] #{pattern}"
        unless pattern instanceof XPath
          if /^\.\.\//.test(pattern) and @parent?
            return @parent.find pattern.replace(/^\.\.\//, ''), opts
          if /^\//.test(pattern) and this isnt @root
            return @root.find pattern, opts
          pattern = XPath.parse pattern, @schema

        @debug "[find] using #{pattern}"
        if opts.root or not @container? or pattern.tag not in [ '/', '..' ]
          @debug "[find] apply #{pattern}"
          @debug @content
          pattern.apply(@content).props ? []
        else switch
          when pattern.tag is '/'  and @parent? then @parent.find pattern, opts
          when pattern.tag is '..' and @parent? then @parent.find pattern.xpath, opts
          else []

### in (pattern)

A convenience routine to locate one or more matching Property
instances based on `pattern` (XPATH or YPATH) from this Model.

      in: (pattern) ->
        try props = @find pattern
        return unless props? and props.length
        return switch
          when props.length > 1 then props
          else props[0]

### do ()

A convenience wrap to a Property instance that holds a function to
perform a Promise-based execution.

Always returns a Promise.

      invoke: ->
        console.warn "DEPRECATION: please use .do() instead"
        @do arguments...

      do: ->
        unless (@binding instanceof Function) or (@content instanceof Function)
          return Promise.reject @error "cannot perform action on a property without function"
        try
          @debug "[do] executing method: #{@name}"
          obj = {}
          obj[kProp] = this
          ctx = @context.with(obj)
          @schema.input?.eval  ctx.state, {}
          @schema.output?.eval ctx.state, {}
          ctx.input = arguments
          # first apply schema bound function (if availble), then
          # execute assigned function (if available and not 'missing')
          if @binding?
            @debug "[do] calling bound function"
            @debug @binding.toString()
            res = @binding.apply ctx, arguments
            ctx.output ?= res
          if @content? and @content isnt @binding
            if (not @binding?) or @content.name isnt 'missing'
              @debug "[do] calling assigned function: #{@content.name}"
              @debug @content.toString()
              ctx.output = @content.apply @container, arguments
          return co =>
            @debug "[do] evaluating output schema"
            ctx.output = yield Promise.resolve ctx.output
            @debug "[do] finish setting output"
            @emit 'done', ctx
            return ctx.output
        catch e
          @debug e
          return Promise.reject e

### error (msg)

Provides more contextual error message pertaining to the Property instance.

      error: (msg, ctx=this) ->
        at = "#{@path}"
        at += @name if at is '/'
        res = new Error "[#{at}] #{msg}"
        res.name = 'PropertyError'
        res.context = ctx
        return res

      debug: (msg) ->
        if debug? then switch typeof msg
          when 'object' then debug msg
          else
            node = this
            prefix = [ @name ]
            prefix.unshift node.name while (node = node.parent)
            debug "[#{prefix.join('/')}] #{msg}"

### inspect

      inspect: ->
        return {
          name:   @schema.tag ? @name
          kind:   @schema.kind
          key:    @key
          xpath:  @path.toString()
          schema: @schema.toJSON tag: false, extended: true
          active: @enumerable
          readonly: not @mutable
        }

### toJSON

This call creates a new copy of the current `Property.content`
completely detached/unbound to the underlying data schema. It's main
utility is to represent the current data state for subsequent
serialization/transmission. It accepts optional argument `tag` which
when called with `false` will not tag the produced object with the
current property's `@name`.

      toJSON: (tag=true) ->
        copy = (src) ->
          return unless src? and typeof src isnt 'function'
          if typeof src is 'object'
            try res = new src.constructor
            catch then res = {}
            for own k, v of src when typeof v isnt 'function'
              res[k] = copy v
            return res
          src.constructor.call src, src
        value = copy @get()
        value ?= [] if @kind is 'list'
        if tag
          name = switch
            when @kind is 'list' then @schema.datakey
            else @name
          "#{name}": value
        else value

## Export Property Class

    module.exports = Property


Refactor status return handling

Refactor status return handling

    redis = require './db/redis'
    mongo = require './db/mongo'

## check()

This is the system check. It retrives the current status from Redis and MongoDB
and perfoms a simple error checking on the returned data before returning to the
user.

Since this is publicly available endpoint, no data is returned, only a `System
OK` message if everything is fine. Errors are logged.

    exports.check = (req, res, next) ->
      cnt = 0
      ret = (err, info) ->
        return if cnt > 2

        if err
          cnt = Math.Infinity
          next err

        else if ++cnt is 2
          res.status 200
          return res.end() if req.method is 'HEAD'
          return res.json message: 'System OK'

      mongo.db.command dbStats: true, ret
      redis.info ret

    redis = require './db/redis'
    mongo = require './db/mongo'

## check()

This is the system check. It retrives the current status from Redis and MongoDB
and perfoms a simple error checking on the returned data before returning to the
user.

Since this is publicly available endpoint, no data is returned, only a `System
OK` message if everything is fine. Errors are logged.

    exports.check = (req, res, next) ->
      cnt = 0
      ret = (err, info) ->
        return if cnt > 2

        if err
          cnt = Math.Infinity
          next err

        else if ++cnt is 2
          res.send 200 if req.method is 'HEAD'
          res.json 200, message: 'System OK'

      mongo.db.command dbStats: true, ret
      redis.info ret


Update supported HTTP methods and error messages

    "use strict"

    express     = require 'express'
    raven       = require 'raven'

    system      = require './system'
    collection  = require './collection'
    document    = require './document'

## Init

    app = express()

### Authentication

This routine is called for all request to the API. It is reponsible for
authenticating the user by validating the `api\_key`. It then sets some request
session variables so they become accessible throughout the entire system during
the rquest.

In future versions of the API this routine will also check the request quota and
blocking the user if the quota is full.

    app.use '/', (req, res, next) ->

      key = req.query.api_key

      return res.json 403, message: 'API key missing' if not key
      return res.json 401, message: 'API key invalid' if not apiKeys[key]

      req.key = key
      req.usr = apiKeys[key]

      next()

### Configuration

    app.use(express.favicon())
    app.use(express.logger(':date :remote-addr - :method :url :status :res[content-length] - :response-time ms')) if not process.env.SILENT
    app.set('json spaces', 0) if app.get('env') isnt 'testing'
    app.use(express.compress())
    app.use(express.json())
    app.disable('x-powered-by')
    app.enable('verbose errors')
    app.set 'port', process.env.PORT_WWW or 8080
    app.use(app.router)

    if process.env.SENTRY_DNS
      app.use raven.middleware.express process.env.SENTRY_DNS
      raven.patchGlobal process.env.SENTRY_DNS

### Error handling

This is the error handler. All errors passed to `next` or exceptions ends up
here. We set the status code to `500` if it is not already defined in the
`Error` object. We then print the error mesage and stack trace to the console
for debug purposes.

Before returning a response to the user the request method is check. HEAD
requests shall not contain any body – this applies for errors as well.

    app.use (err, req, res, next) ->
      res.status(err.status or 500)

      console.error err.message
      console.error err.stack

      return res.end() if req.method is 'HEAD'
      return res.json message: err.message or 'Ukjent feil'

This the fmous 404 Not Found handler. If no route configuration for the request
is found, it ends up here. We don't do much fancy about it – just a standard
error message and HTTP status code.

    app.use (req, res) -> res.json 404, message: "Resurs ikke funnet"

### API keys

This is the dirty part. Here are all the keys to the kingdom. These will be
moved to the database and retrieved when the server starts. Just need to find
the time to do it.

    apiKeys =
      dnt: 'DNT'
      nrk: 'NRK'

      '30ad3a3a1d2c7c63102e09e6fe4bb253': 'TurApp'
      'b523ceb5e16fb92b2a999676a87698d1': 'Pingdom'

      '4c802ac2315ab24db9c992cc6eea0278': 'DNT' # ETA
      'de2986ac75c5af9d7f92a26f37dc1b77': 'DNT' # sherpa2.api
      '5dd5a39057cb479c3c4bce7f9eae5e6c': 'DNT' # dev.ut.no
      '146bbe01b477e9e07e85e0ddd3f5095a': 'DNT' # beta.ut.no
      'e6fa27292ffbcc689c49179c47bc708e': 'DNT' # prod.ut.no

## GET /

    app.get '/', (req, res) ->
      res.json message: 'Here be dragons'

## GET /system

Hsssssj!!! Don't tell anyone about the secret system API endpoint!

    app.get '/system', system.info

## GET /CloudHealthCheck

> So...You’re seeing the dotCloud active health check looking to make sure that
> your service is up. There is no way for you to disable it, but you can prevent
> it and you can handle it [1]!

[1] [dotCloud](http://docs.dotcloud.com/tutorials/more/cloud-health-check/)

    app.get '/CloudHealthCheck', system.check

## GET /objekttyper

    app.get '/objekttyper', (req, res, next) ->
      res.json 200, ['turer', 'steder', 'områder', 'grupper', 'arrangementer', 'bilder']

## ALL /{collection}

    app.param 'collection', collection.param
    app.all '/:collection', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then collection.options req, res, next
        when 'HEAD', 'GET' then collection.get req, res, next
        when 'POST' then collection.post req, res, next
        else res.json 405, message: "HTTP Method #{req.method.toUpperCase()} Not Allowed"

## ALL /{collection}/{objectid}

    app.param 'objectid', document.param
    app.options '/:collection/:ojectid', document.options
    app.all '/:collection/:objectid', document.all, (req, res, next) ->
      switch req.method
        when 'HEAD', 'GET' then document.get req, res, next
        when 'PUT' then document.put req, res, next
        when 'PATCH' then document.patch req, res, next
        when 'DELETE' then document.delete req, res, next
        else res.json 405, message: "HTTP Method #{req.method.toUpperCase()} Not Allowed"

## Start

Ok, so if the server is running in stand-alone mode i.e. there is not
`module.parent` then continue with starting the databse and listening to a port.

    if not module.parent
      require('./db/redis')
      require('./db/mongo').once 'ready', ->
        console.log 'Database is open...'

        app.listen app.get('port'), ->
          console.log "Server is listening on port #{app.get('port')}"

However, if there is a `module.parent` don't do all the stuff above. This means
that there is some program that is including the server from it, e.g a test, and
hence it should not listen to a port for incomming connections and rather just
return the application instance so that we can do some testing on it.

    else
      module.exports = app

    "use strict"

    express     = require 'express'
    raven       = require 'raven'

    system      = require './system'
    collection  = require './collection'
    document    = require './document'

## Init

    app = express()

### Authentication

This routine is called for all request to the API. It is reponsible for
authenticating the user by validating the `api\_key`. It then sets some request
session variables so they become accessible throughout the entire system during
the rquest.

In future versions of the API this routine will also check the request quota and
blocking the user if the quota is full.

    app.use '/', (req, res, next) ->

      key = req.query.api_key

      return res.json 403, message: 'API key missing' if not key
      return res.json 401, message: 'API key invalid' if not apiKeys[key]

      req.key = key
      req.usr = apiKeys[key]

      next()

### Configuration

    app.use(express.favicon())
    app.use(express.logger(':date :remote-addr - :method :url :status :res[content-length] - :response-time ms')) if not process.env.SILENT
    app.set('json spaces', 0) if app.get('env') isnt 'testing'
    app.use(express.compress())
    app.use(express.json())
    app.disable('x-powered-by')
    app.enable('verbose errors')
    app.set 'port', process.env.PORT_WWW or 8080
    app.use(app.router)

    if process.env.SENTRY_DNS
      app.use raven.middleware.express process.env.SENTRY_DNS
      raven.patchGlobal process.env.SENTRY_DNS

### Error handling

This is the error handler. All errors passed to `next` or exceptions ends up
here. We set the status code to `500` if it is not already defined in the
`Error` object. We then print the error mesage and stack trace to the console
for debug purposes.

Before returning a response to the user the request method is check. HEAD
requests shall not contain any body – this applies for errors as well.

    app.use (err, req, res, next) ->
      res.status(err.status or 500)

      console.error err.message
      console.error err.stack

      return res.end() if req.method is 'HEAD'
      return res.json message: err.message or 'Ukjent feil'

This the fmous 404 Not Found handler. If no route configuration for the request
is found, it ends up here. We don't do much fancy about it – just a standard
error message and HTTP status code.

    app.use (req, res) -> res.json 404, message: "Resurs ikke funnet"

### API keys

This is the dirty part. Here are all the keys to the kingdom. These will be
moved to the database and retrieved when the server starts. Just need to find
the time to do it.

    apiKeys =
      dnt: 'DNT'
      nrk: 'NRK'

      '30ad3a3a1d2c7c63102e09e6fe4bb253': 'TurApp'
      'b523ceb5e16fb92b2a999676a87698d1': 'Pingdom'

      '4c802ac2315ab24db9c992cc6eea0278': 'DNT' # ETA
      'de2986ac75c5af9d7f92a26f37dc1b77': 'DNT' # sherpa2.api
      '5dd5a39057cb479c3c4bce7f9eae5e6c': 'DNT' # dev.ut.no
      '146bbe01b477e9e07e85e0ddd3f5095a': 'DNT' # beta.ut.no
      'e6fa27292ffbcc689c49179c47bc708e': 'DNT' # prod.ut.no

## GET /

    app.get '/', (req, res) ->
      res.json message: 'Here be dragons'

## GET /system

Hsssssj!!! Don't tell anyone about the secret system API endpoint!

    app.get '/system', system.info

## GET /CloudHealthCheck

> So...You’re seeing the dotCloud active health check looking to make sure that
> your service is up. There is no way for you to disable it, but you can prevent
> it and you can handle it [1]!

[1] [dotCloud](http://docs.dotcloud.com/tutorials/more/cloud-health-check/)

    app.get '/CloudHealthCheck', system.check

## GET /objekttyper

    app.get '/objekttyper', (req, res, next) ->
      res.json 200, ['turer', 'steder', 'områder', 'grupper', 'arrangementer', 'bilder']

## ALL /{collection}

    app.param 'collection', collection.param
    app.all '/:collection', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then collection.options req, res, next
        when 'HEAD', 'GET' then collection.get req, res, next
        when 'POST' then collection.post req, res, next
        when 'PUT'  then collection.put req, res, next
        when 'PATCH' then collection.patch req, res, next
        else res.json 405, message: 'HTTP method not supported'

## ALL /{collection}/{objectid}

    app.param 'objectid', document.param
    app.all '/:collection/:objectid', (req, res, next) ->
      switch req.method
        when 'OPTIONS' then document.options req, res, next
        when 'HEAD', 'GET' then document.get req, res, next
        when 'PUT' then document.put req, res, next
        when 'PATCH' then document.patch req, res, next
        when 'DELETE' then document.delete req, res, next
        else res.json 405, message: 'HTTP method not supported'

## Start

Ok, so if the server is running in stand-alone mode i.e. there is not
`module.parent` then continue with starting the databse and listening to a port.

    if not module.parent
      require('./db/redis')
      require('./db/mongo').once 'ready', ->
        console.log 'Database is open...'

        app.listen app.get('port'), ->
          console.log "Server is listening on port #{app.get('port')}"

However, if there is a `module.parent` don't do all the stuff above. This means
that there is some program that is including the server from it, e.g a test, and
hence it should not listen to a port for incomming connections and rather just
return the application instance so that we can do some testing on it.

    else
      module.exports = app