diff --git a/osh/osh.asdl b/osh/osh.asdl
index 03d99c2..a474560 100644
--- a/osh/osh.asdl
+++ b/osh/osh.asdl
@@ -15,16 +15,21 @@
 -- * Brace expansion: should this be another kind of 'word'?  It can be
 --   expanded at compile time.
 -- * let arithmetic (rarely used)
--- * coprocesses
+-- * coprocesses -- two kinds
+-- * time builtin can take a block
 
 -- TODO: Preserve these source differences:
--- * $foo vs. ${foo}.  VarSub vs. BracedVarSub
--- * 1 + 2*3  vs.  1 + (2*3)  or even 1 + ((2*3))
--- * [[ (1 == 1) ]] vs [[ 1 == 1 ]]
+-- * order of redirects: 'echo >out.txt hi'  vs echo hi >out.txt
+--   * In the printer, I want to preserve line breaks!  foo \bar?
+-- * parens
+--   * 1 + 2*3  vs.  1 + (2*3)  or even 1 + ((2*3))
+--   * [[ (1 == 1) ]] vs [[ 1 == 1 ]]
 -- * HereDoc vs HereWord.  I collapsed them.
 -- * $(( 1 + 2 )) vs $[1 + 2]  (bash-specific, used by Aboriginal)
--- * Don't fill in file descriptor unless user specified it, e.g. echo < in.txt
---   vs. echo 1< in.txt
+--
+-- Found to be not strictly necessary for oil conversion
+-- * foo() { } vs function foo { } -- ksh 
+-- * $'n' vs 'n'  -- one of them just has EscapedLiteralPart
 
 module osh
 {
@@ -47,20 +52,23 @@ module osh
   -- begin is optional with ${array::1}
   | Slice(arith_expr? begin, arith_expr? length)
 
+  -- TODO: Constructors should be scoped?  array_item::Pair?
   array_item = 
-    ArrayWord(word w)  -- # TODO: make them scoped?  array_item::Pair?
+    ArrayWord(word w)
   | ArrayPair(word key, word value)
 
   word_part = 
-    ArrayLiteralPart(word* words) -- TODO: should be array_item* items
+    -- TODO: should be array_item* items.  They CAN be mixed, like a=([x]=y z)
+    ArrayLiteralPart(word* words)
   | LiteralPart(token token)
   | EscapedLiteralPart(token token)
   | SingleQuotedPart(token* tokens)
   | DoubleQuotedPart(word_part* parts)
-  | VarSubPart(string name,
-               id? prefix_op,  -- prefix # or ! operators
-               bracket_op? bracket_op
-               suffix_op? suffix_op)
+  | SimpleVarSub(token token)
+  | BracedVarSub(token token,
+                id? prefix_op,  -- prefix # or ! operators
+                bracket_op? bracket_op
+                suffix_op? suffix_op)
   | TildeSubPart(string prefix)
   | CommandSubPart(command command_list)
   | ArithSubPart(arith_expr anode)
@@ -104,41 +112,54 @@ module osh
   | HereDoc(id op_id, word? arg_word, int fd, int do_expansion,
             string here_end, bool was_filled)
 
-  assign_scope = Global | Local
-  assign_flags = Export | ReadOnly
-  assign_pair = (lvalue lhs, word rhs)
+  assign_pair = (lvalue lhs, word? rhs)
   env_pair = (string name, word val)
 
-  -- Homogeneous version
+  -- Each arm tests one word against multiple words
+  case_arm = (word* pat_list, command action)
+  if_arm = (command cond, command action)
+
+  iterable = 
+    IterArgv
+  | IterArray(word* words)
+
+  -- TODO: Make field names consistent: child vs expr, etc.
+
   command = 
     NoOp
+  -- TODO: respect order 
   | SimpleCommand(word* words, redir* redirects, env_pair* more_env)
-  | Assignment(assign_scope scope,
-               assign_flags* flags,
-               word* words,  -- names mentioned without a binding
-               assign_pair* pairs)  -- empty redirects for polymorphism?
-  | Fork(command* children)  -- shell only allows one command
+  | Sentence(command command, token terminator)
+  -- TODO: parse flags -r -x; -a and -A aren't needed
+  | Assignment(id keyword, assign_pair* pairs)
   | Pipeline(command* children, bool negated, int* stderr_indices)
-  -- | AndOr(command* children, and_or* ops)
+  -- TODO: Should be left and right
   | AndOr(command* children, id op_id)
-  -- A command list is used for for/if/while conditions and bodies.  No redirects.
+  -- TODO: Get rid of CommandList?  No redirects, so can be a plain list.
   | CommandList(command* children)
-  -- A brace group is a compound command, with redirects.
+  -- Part of for/while/until.  Can have one or more children.
+  | DoGroup(command child, redir* redirects)
+  -- A brace group is a compound command, with redirects.  Can have one or more
+  -- children.
   | BraceGroup(command* children, redir* redirects)
+  -- Can have one or more children.
   | Subshell(command* children, redir* redirects)
   | DParen(arith_expr child, redir* redirects)
   | DBracket(bool_expr expr, redir* redirects)
   -- do_arg_iter: whether to implicitly loop over "$@"
+  -- TODO: Make iter_words a sum type.  iterable for_words
   | ForEach(string iter_name, word* iter_words, bool do_arg_iter,
-            command* children, redir* redirects)
+            command body, redir* redirects)
   -- C-style for loop.  Any of the 3 expressions can be omitted.
+  -- TODO: body is required, but only optional here because of initialization
+  -- order.
   | ForExpr(arith_expr? init, arith_expr? cond, arith_expr? update,
-            command* children, redir* redirects)
-  | While(command* children, redir* redirects)
-  | Until(command* children, redir* redirects)
-  | If(command* children, redir* redirects)
-  | Case(word to_match, word* pat_word_list, command* children, redir* redirects)
-  | FuncDef(string name, command* children, redir* redirects)
+            command? body, redir* redirects)
+  | While(command cond, command body, redir* redirects)
+  | Until(command cond, command body, redir* redirects)
+  | If(if_arm* arms, command? else_action, redir* redirects)
+  | Case(word to_match, case_arm* arms, redir* redirects)
+  | FuncDef(string name, command body, redir* redirects)
 
   and_or = DAmp | DPipe
 
@@ -146,6 +167,11 @@ module osh
   -- |& in osh; |- in oil.
   -- pipe_op = Pipe | PipeAndStderr
 
+  --  NOTE: Do we even need these types?  Arena already has methods.  They can
+  --  We just need to go from text -> text.  For execution, we'll be compiling
+  -- to a different format.  We also won't bootstrap with osh code -- only oil
+  -- code.  shell can call oil builtins if necessary.
+
   -- A node with full debug info
   -- All other nodes should have span_id?  int _loc or int _begin, int _end.
   -- It can be further compressed perhaps, like a varint.