code: def handle_cmd(self, cmd):
          cmd = cmd.strip()
          segments = []
          for s in cmd.split():
              if s.startswith('
                  break
              segments.append(s)
          args = []
          if not len(segments):
              return
          while segments:
              cur_cmd = "_".join(segments)
              if cur_cmd in self._cmd_methods:
                  argc = self._cmd_argc[cur_cmd]
                  if argc is not None and len(args) != argc:
                      msg('command {0} expects {1} argument(s), got {2}',
                          " ".join(segments), argc, len(args))
                      return
                  self._cmd_methods[cur_cmd](args)
                  return
              args.insert(0, segments.pop())
          prefix = '_'.join(args) + '_'
          matches = filter(
              lambda cmd: cmd.startswith(prefix), self._cmd_methods.keys())
          candidates = set([])
          for m in matches:
              if len(m) <= len(prefix):
                  continue
              m = m[len(prefix):]
              if '_' in m:
                  m = m[:m.index('_')]
              candidates.add(m)
          if len(candidates):
              msg('command "{0}" needs more arguments:', ' '.join(args))
              for c in candidates:
                  msg('    {0}', c)
          else:
              msg('command "{0}" invalid; type ' +
                  'help or use <TAB> for a list of commands',
                  ' '.join(args))