   #         # Start sending other commands here.
   #     client.connect ...
   #
-  auth: (password,cb)       -> @send "auth #{password}", null, cb
+  auth: (password,cb)       -> @send "auth #{password}", cb
 
   # connect() and linger() are used in server mode.
-  connect: (cb)             -> @send "connect", null, cb    # Outbound mode
-
-  linger: (cb)              -> @send "linger", null, cb     # Outbound mode
+  connect: (cb)             -> @send "connect", cb    # Outbound mode
+
+  linger: (cb)              -> @send "linger", cb     # Outbound mode
 
   # Send the exit command to the FreeSwitch socket.
-  exit: (cb)                -> @send "exit", null, cb
+  exit: (cb)                -> @send "exit", cb
 
   #### Event logging commands
   log: (level,cb) ->
     [level,cb] = [null,level] if typeof(level) is 'function'
     if level?
-      @send "log #{level}", null, cb
+      @send "log #{level}", cb
     else
-      @send "log", null, cb
-
-  nolog: (cb)                 -> @send "nolog", null, cb
+      @send "log", cb
+
+  nolog: (cb)                 -> @send "nolog", cb
 
   #### Message sending
   # Send Message (to a UUID)

#
# If you'd like to get realtime channel variables and synchronous commands, do
#
#     server = esl.createCallServer true
#
#     server.on 'CONNECT', (req,res) ->
#       res.execute 'verbose_events', null, (req,res) ->
#         # You may now access realtime variables as
#         foo = req.body.variable_foo
#         res.execute 'play-file', 'voicemail/vm-hello', (req,res) ->
#           # This call with wait for the command to finish
#           # Your application continues here
#
#     server.listen 7000
#
# Note that although the socket command was called (in the dialplan above) with
# the "async" parameter, createCallServer is processing the commands synchronously.
# Of course you can work synchronously without using verbose_events; you may still
# obtain realtime values by using the API (lookup the "eval" command).
# However you cannot use verbose_events asynchronously, unless you capture the
# CHANNEL_EXECUTE_COMPLETE event.
#
# An asynchronous server will look this way:
#
#     server = esl.createCallServer()
#
#     server.on 'CONNECT', (req,res) ->
#       # Start processing the call
#       # Channel data is available as req.channel_data
#       # Channel UUID is available as req.unique_id
#       # For example:
#       uri = req.channel_data.variable_sip_req_uri
#
#     # Other FreeSwitch channel events are available as well:
#     server.on 'CHANNEL_ANSWER', (req,res) ->

class eslResponse
  constructor: (@socket) ->

  register_callback: (event,cb) ->
    @socket.on event, (req,res) =>
      @socket.removeAllListeners event
      cb req,res

  # A generic way of sending commands to FreeSwitch.
  #
  #      send (string,array,function(req,res){})
  #
  # This is normally not used directly.
  # The array and callback are both optional.

  send: (command,args,cb) ->

    # The arguments parameter is optional.
    if typeof args is 'function' and not cb?
      [cb,args] = [args,null]

    if exports.debug
      util.log util.inspect command: command, args: args

    if cb? then @register_callback 'esl_command_reply', cb

    # Send the command out.
    try
      @socket.write "#{command}\n"
      if args?
        for key, value of args
          @socket.write "#{key}: #{value}\n"
      @socket.write "\n"
    catch e
      @socket.emit 'esl_error', error:e

  on: (event,listener) -> @socket.on(event,listener)

