def parse (cls, line, lineno, log, cmddict=None):
    """Parses a SeqCmdAttrs from a line of text and returns it or None.
    Warning and error messages are logged via the SeqMsgLog log.
    """
    start  = line.find('{')
    stop   = line.find('}')
    pos    = SeqPos(line, lineno, start + 1, stop)
    result = cls(None, pos)

    if start >= 0 and stop >= start:
      attrs = { }
      pairs = line[start + 1:stop].split(',')

      for item in pairs:
        ncolons = item.count(':')
        if ncolons == 0:
          log.error('Missing colon in command attribute "%s".' % item, pos)
        elif ncolons > 1:
          log.error('Too many colons in command attribute "%s".' % item, pos)
        else:
          name, value = (s.strip() for s in item.split(':'))
          attrs[name] = value

      result = cls(attrs, pos)

    elif start != -1 or stop != -1:
      log.error('Incorrect command attribute curly brace placement.', pos)

    return result
Parses a SeqCmdAttrs from a line of text and returns it or None.
    Warning and error messages are logged via the SeqMsgLog log.