def METHOD_NAME(ptree, shell, interactive):
  ps, cat, subshell = None, None, None
  if shell == 'bash':
    ptree.assert_child_count(2)
    for child in ptree.children:
      if len(child.children) == 1:
        subshell = child
        ps = child.children[0]
      elif len(child.children) == 0:
        cat = child
      else:
        print('[%s] has unexpected child [%s]' % (ptree.proc, child), file=sys.stderr)
        sys.exit(1)
    if not subshell:
      print('missing expected subshell', file=sys.stderr)
      sys.exit(1)
  else:
    ptree.assert_child_count(2)
    # NOTE: Ideally we would check the comm field of the children, but `ps` may
    # have run before some of them called exec(). Luckily we're only checkign
    # that both children are in their own group in this case, so we just
    # guess...
    ps = ptree.children[0]
    cat = ptree.children[1]
  if not ps:
    print('missing ps', file=sys.stderr)
    sys.exit(1)
  if not cat:
    print('missing cat', file=sys.stderr)
    sys.exit(1)
  if not interactive:
    ps.proc.assert_pgid(ptree.proc.pgid)
    cat.proc.assert_pgid(ptree.proc.pgid)
    if subshell:
      subshell.proc.assert_pgid(ptree.proc.pgid)
  else:
    if shell == 'bash':
      # bash is interesting
      subshell.proc.assert_pgid(ptree.proc.pid)
      ps.proc.assert_pgid(ptree.proc.pid)
      cat.proc.assert_pgid(cat.proc.pid)
    else:
      # osh and zsh put all children in their own group
      ps.proc.assert_pgid(ps.proc.pid)
      cat.proc.assert_pgid(cat.proc.pid)