'Decodes incoming MSDP data.
Args:
data (str or list): MSDP data.
Notes:
Clients should always send MSDP data on
one of the following forms:
cmdname \'\'          -> [cmdname, [], {}]
cmdname val         -> [cmdname, [val], {}]
cmdname array       -> [cmdname, [array], {}]
cmdname table       -> [cmdname, [], {table}]
cmdname array cmdname table -> [cmdname, [array], {table}]
Observe that all MSDP_VARS are used to identify cmdnames,
so if there are multiple arrays with the same cmdname
given, they will be merged into one argument array, same
for tables. Different MSDP_VARS (outside tables) will be
identified as separate cmdnames.'

def decode_msdp(self, data):

    if hasattr(data, '__iter__'):
        data = ''.join(data)
    tables = {}
    arrays = {}
    variables = {}
    for (key, table) in msdp_regex_table.findall(data):
        tables[key] = ({} if (key not in tables) else tables[key])
        for varval in msdp_regex_var.split(table)[1:]:
            (var, val) = msdp_regex_val.split(varval, 1)
            if var:
                tables[key][var] = val
    data_no_tables = msdp_regex_table.sub('', data)
    for (key, array) in msdp_regex_array.findall(data_no_tables):
        arrays[key] = ([] if (key not in arrays) else arrays[key])
        parts = msdp_regex_val.split(array)
        if (len(parts) == 2):
            arrays[key].append(parts[1])
        elif (len(parts) > 1):
            arrays[key].extend(parts[1:])
    data_no_tables_or_arrays = msdp_regex_array.sub('', data_no_tables)
    for varval in msdp_regex_var.split(data_no_tables_or_arrays):
        parts = msdp_regex_val.split(varval)
        if (len(parts) == 2):
            variables[parts[0]] = parts[1]
        elif (len(parts) > 1):
            variables[parts[0]] = parts[1:]
    cmds = {}
    for (key, table) in tables.iteritems():
        (args, kwargs) = ([], table)
        if (key in arrays):
            args.extend(arrays.pop(key))
        if (key in variables):
            args.append(variables.pop(key))
        cmds[key] = [args, kwargs]
    for (key, arr) in arrays.iteritems():
        (args, kwargs) = (arr, {})
        if (key in variables):
            args.append(variables.pop(key))
        cmds[key] = [args, kwargs]
    for (key, var) in variables.iteritems():
        cmds[key] = [[var], {}]
    self.protocol.data_in(**cmds)
