     srcPort = componentLib.outputPortById(nodeLookup(graph, srcNode).component, cmdData.readUInt8(2)).name
     targetNode = nodeNameById(graph.nodeMap, cmdData.readUInt8(3))
     targetPort = componentLib.inputPortById(nodeLookup(graph, targetNode).component, cmdData.readUInt8(4)).name
-    type = nodeNameById(cmdFormat.packetTypes, cmdData.readUInt8(5))
-    data = undefined
-    # TODO: move next to dataLiteralToCommand, for symmetry
-    if type == 'Boolean'
-      data = if cmdData.readUInt8(6) then true else false
-    else if type == 'Void'
-      data = null
-    else if type == 'Integer' or type == 'Float'
-      data = cmdData.readInt16LE(6)
-    else if type == 'Byte'
-      data = cmdData.readUInt8(6)
-    else if type == 'BracketStart' or type == 'BracketEnd'
-      data = type
-    else
-      console.log 'Unknown data type in PacketSent: ', type
+    dataOffset = 5
+    { data, type } = deserializeData cmdData, dataOffset
     handler 'SEND', srcNode, srcPort, type, data, targetNode, targetPort
   else if cmd == cmdFormat.commands.SubgraphPortConnected.id
     direction = if cmdData.readUInt8(1) then 'output' else 'input'

  writeCmd.apply this, args
  return b

dataToCommand = (data, tgt, tgtPort) ->
    # XXX: wrong way around, literal should call this, not
    if Array.isArray data
        literal = JSON.stringify data

#        literal = "\"#{data}\""
    else
        literal = data+''
    return dataLiteralToCommandDescriptions literal

# literal is a string, typically from a .FBP graph
dataLiteralToCommandDescriptions = (literal) ->
  commands = [] # [ { type: '', data: ?Buffer } ]
  literal = literal.replace('^"|"$', '')

  basic = serializeData literal
  if basic
    return [ basic ]

  # compound type / stream
  try
    value = JSON.parse(literal)
  catch err
    throw 'Unknown IIP data type for literal \'' + literal + '\' :' + err

  if Array.isArray value
    commands.push { type: "BracketStart" }
    for val in value
        subs = dataToCommandDescriptions val
        commands = commands.concat subs
    commands.push { type: "BracketEnd" }
    return commands

  throw 'Unknown IIP data type for literal \'' + literal + '\''

serializeCommands = (commands, tgt, tgtPort) ->
  buffers = []
  for cmd in commands
    type = cmdFormat.packetTypes[cmd.type].id
    header = new Buffer 4
    header.writeInt8 cmdFormat.commands.SendPacket.id, 0
    header.writeUInt8 tgt, 1
    header.writeUInt8 tgtPort, 2
    header.writeUInt8 type, 3
    data = cmd.data
    if not data
        data = new Buffer cmdFormat.commandSize-4
        data.fill 0
    buffers.push header
    buffers.push data

  r = Buffer.concat buffers
  return r

dataLiteralToCommand = (literal, tgt, tgtPort) ->
  commands = dataLiteralToCommandDescriptions literal
  return serializeCommands commands, tgt, tgtPort

dataToCommand = (data, tgt, tgtPort) ->
  commands = dataToCommandDescriptions data
  return serializeCommands commands, tgt, tgtPort

findPort = (componentLib, graph, nodeName, portName) ->
  isOutput = false
