anchor.diff:                      if ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof<_ option> then
                           let genTy = ty.GetGenericArguments().[0]
                           if genTy = typeof<string> then
  -                            (field.Name, Optional((makeName field.Name), description, PrimitiveString))
  +                            (field.Name, ArgOptional((makeName field.Name), description, PrimitiveString))
                           else if genTy = typeof<int> then
  -                            (field.Name, Optional((makeName field.Name), description, PrimitiveInt))
  +                            (field.Name, ArgOptional((makeName field.Name), description, PrimitiveInt))
                           else if genTy = typeof<double> then
  -                            (field.Name, Optional((makeName field.Name), description, PrimitiveDouble))
  +                            (field.Name, ArgOptional((makeName field.Name), description, PrimitiveDouble))
                           else if genTy = typeof<DateTime> then
  -                            (field.Name, Optional((makeName field.Name), description, PrimitiveDateTime))
  +                            (field.Name, ArgOptional((makeName field.Name), description, PrimitiveDateTime))
                           else if genTy = typeof<bool> then
  -                            (field.Name, OptionalBool((makeName field.Name), description))
  +                            (field.Name, ArgOptionalBool((makeName field.Name), description))
                           else if genTy |> FSharpType.IsUnion then
                               let cases = FSharpType.GetUnionCases genTy
                               let isSimple = cases |> Array.map (fun caseInfo -> caseInfo.GetFields() |> Array.isEmpty) |> Array.tryFind not |> Option.isNone
                               if isSimple then
  -                                (field.Name, Optional((makeName field.Name), description, PrimitiveUnion(genTy)))
  +                                (field.Name, ArgOptional((makeName field.Name), description, PrimitiveUnion(genTy)))
                               else
  -                                (field.Name, Invalid)
  +                                (field.Name, ArgInvalid)
                           else
  -                            (field.Name, Invalid)
  +                            (field.Name, ArgInvalid)
  +                    else if ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof<_ list> then
  +                        let genTy = ty.GetGenericArguments().[0]
  +                        if genTy = typeof<string> then
  +                            (field.Name, ArgList((makeName field.Name), description, PrimitiveString))
  +                        else if genTy = typeof<int> then
  +                            (field.Name, ArgList((makeName field.Name), description, PrimitiveInt))
  +                        else if genTy = typeof<double> then
  +                            (field.Name, ArgList((makeName field.Name), description, PrimitiveDouble))
  +                        else if genTy = typeof<DateTime> then
  +                            (field.Name, ArgList((makeName field.Name), description, PrimitiveDateTime))
  +                        else if genTy = typeof<bool> then
  +                            (field.Name, ArgList((makeName field.Name), description, PrimitiveBool))
  +                        else if genTy |> FSharpType.IsUnion then
  +                            let cases = FSharpType.GetUnionCases genTy
  +                            let isSimple = cases |> Array.map (fun caseInfo -> caseInfo.GetFields() |> Array.isEmpty) |> Array.tryFind not |> Option.isNone
  +                            if isSimple then
  +                                (field.Name, ArgList((makeName field.Name), description, PrimitiveUnion(genTy)))
  +                            else
  +                                (field.Name, ArgInvalid)
  +                        else
  +                            (field.Name, ArgInvalid)
                       else if ty |> FSharpType.IsRecord then
                           let a = getArgs ty
  -                        if a = Invalid then (field.Name, Invalid)
  +                        if a = ArgInvalid then (field.Name, ArgInvalid)
                           else (field.Name, a)
                       else if ty |> FSharpType.IsUnion then
                           let cases = FSharpType.GetUnionCases ty
                           let isSimple = cases |> Array.map (fun caseInfo -> caseInfo.GetFields() |> Array.isEmpty) |> Array.tryFind not |> Option.isNone
                           if isSimple then
  -                            (field.Name, Required((makeName field.Name), description, PrimitiveUnion(ty)))
  +                            (field.Name, ArgRequired((makeName field.Name), description, PrimitiveUnion(ty)))
                           else
                               (field.Name, getArgs ty)
                       else if ty = typeof<string> then
  -                        (field.Name, Required((makeName field.Name), description, PrimitiveString))
  +                        (field.Name, ArgRequired((makeName field.Name), description, PrimitiveString))
                       else if ty = typeof<int> then
  -                        (field.Name, Required((makeName field.Name), description, PrimitiveInt))
  +                        (field.Name, ArgRequired((makeName field.Name), description, PrimitiveInt))
                       else if ty = typeof<double> then
  -                        (field.Name, Required((makeName field.Name), description, PrimitiveDouble))
  +                        (field.Name, ArgRequired((makeName field.Name), description, PrimitiveDouble))
                       else if ty = typeof<DateTime> then
  -                        (field.Name, Required((makeName field.Name), description, PrimitiveDateTime))
  +                        (field.Name, ArgRequired((makeName field.Name), description, PrimitiveDateTime))
                       else if ty = typeof<bool> then
  -                        (field.Name, Required((makeName field.Name), description, PrimitiveBool))
  +                        (field.Name, ArgRequired((makeName field.Name), description, PrimitiveBool))
                       else
  -                        (field.Name, Invalid))
  +                        (field.Name, ArgInvalid))
               |> fun x ->
  -                let isInvalid = x |> Array.map snd |> Array.tryFind (function | Invalid -> true | _ -> false) |> Option.isSome
  -                if isInvalid then Invalid
  -                else Record(ty, x)
  +                let isInvalid = x |> Array.map snd |> Array.tryFind (function | ArgInvalid -> true | _ -> false) |> Option.isSome
  +                if isInvalid then ArgInvalid
  +                else ArgRecord(ty, x)
           else
  -            Invalid
  +            ArgInvalid
   
       let rec private doParse typeInfo (args:string[]) : (string[] * ArgParserDataInfo) =
           match typeInfo with
  -        | Required(matchString, _, ty) ->
  +        | ArgRequired(matchString, _, ty) ->
               let i = args |> Array.tryFindIndex (fun x -> x = matchString)
               if i |> Option.isNone then
                   (args, RequiredData(ty, None))
  
positive.code:                 (fun caseInfo ->
                      let fields = caseInfo.GetFields()
                      if fields.Length <> 1 then
                          (caseInfo.Name, Invalid)
                      else
                          let field = fields.[0]
                          let ty = field.PropertyType
                          (caseInfo.Name, (getArgs ty)))
              |> fun x ->
                  let isInvalid = x |> Array.map snd |> Array.tryFind (function | Invalid -> true | _ -> false) |> Option.isSome
                  if isInvalid then Invalid
                  else Union(ty, x)
          else if (FSharpType.IsRecord ty) then
              FSharpType.GetRecordFields(ty)
              |> Array.map
  
negative.code:                             ""
                      let e = sprintf "%s}\n" (String.Join("", [1 .. i] |> List.toArray |> Array.map (fun _ -> " ")))
                      s + a + e
                  | ArgUnion(ty, info) ->
                      info
                      |> Array.fold
                          (fun a (name, info) ->
  