anchor.diff:  //        | _ -> comp.AddCompiledMethod(internals, meth, Metadata.Instance name, impl)
   //        meth
   
  -    let getRouteShape (t: System.Type) =
  -        let endpoint =
  -            match t.GetCustomAttributes(typeof<EndPointAttribute>, false) with
  -            | [| :? EndPointAttribute as attr |] -> attr.EndPoint
  -            | _ -> "/"
  -        let fields =
  -            t.GetFields(BF.Instance ||| BF.Public ||| BF.NonPublic)
  -            |> Array.map (fun f -> nameOf f, f.FieldType)
  -            |> List.ofArray
  -        let isHole (n: string) = n.StartsWith "{" && n.EndsWith "}"
  -        match endpoint.[endpoint.IndexOf('/') + 1 ..].Split([|'/'|], StringSplitOptions.RemoveEmptyEntries) with
  -        | [||] ->
  -            if List.isEmpty fields then MetaRoot else MetaPath (None, fields)
  -        | [| name |] when not (isHole name) -> MetaPath (Some name, fields)
  -        | a ->
  -            let name, a =
  -                if isHole a.[0] then
  -                    None, a
  -                else
  -                    Some a.[0], a.[1..]
  -            let args =
  -                a.[1..]
  -                |> Array.map (fun n ->
  -                    if isHole n then
  -                        let name = n.[1..n.Length-2]
  -                        match fields |> List.tryFind (fun (n, _) -> name = n) with
  -                        | Some f -> f
  -                        | None -> failwithf "Path argument doesn't correspond to a field: %s" n
  -                    else
  -                        failwith "Path arguments must be of the shape: {fieldName}")
  -                |> List.ofArray
  -            MetaPath (name, args)
  +    let getRouteShape (t: Type) =
  +        match t with
  +        | ConcreteType td ->
  +            if td.Entity = listT then
  +                let itemT = td.Generics.[0]
  +                let fromArray =
  +                    Hashed {
  +                        MethodName = "ToList"
  +                        Parameters = [ArrayType (GenericType 0, 1)]
  +                        ReturnType = listOf (GenericType 0)
  +                        Generics = 1
  +                    }
  +                let x = Id.New()
  +                MetaSequence (
  +                    Lambda([x], Call (None, arrayModule, concrete(fromArray, [itemT]), [Var x])),
  +                    itemT
  +                )
  +            else
  +                let meth args res =
  +                    Hashed {
  +                        MethodName = t.TypeDefinition.Value.FullName
  +                        Parameters = args
  +                        ReturnType = res
  +                        Generics = 0
  +                    }
  +                let parseMeth = meth [listOf stringT] (optionOf (TupleType [t; listOf stringT]))
  +                match comp.LookupMethodInfo(parsersT, parseMeth) with
  +                | Metadata.LookupMemberError _ ->
  +                    let ctor, t' = getDefaultCtor t
  +                    let endpoint =
  +                        match t'.GetCustomAttributes(typeof<EndPointAttribute>, false) with
  +                        | [| :? EndPointAttribute as attr |] -> attr.EndPoint
  +                        | _ -> "/"
  +                    let fields =
  +                        t'.GetFields(BF.Instance ||| BF.Public ||| BF.NonPublic)
  +                        |> Array.map (fun f -> nameOf f, f.FieldType)
  +                        |> List.ofArray
  +                    let isHole (n: string) = n.StartsWith "{" && n.EndsWith "}"
  +                    match endpoint.[endpoint.IndexOf('/') + 1 ..].Split([|'/'|], StringSplitOptions.RemoveEmptyEntries) with
  +                    | [||] -> MetaObject (ctor, None, fields)
  +                    | [| name |] when not (isHole name) -> MetaObject (ctor, Some name, fields)
  +                    | a ->
  +                        let name, a =
  +                            if isHole a.[0] then
  +                                None, a
  +                            else
  +                                Some a.[0], a.[1..]
  +                        let args =
  +                            a.[1..]
  +                            |> Array.map (fun n ->
  +                                if isHole n then
  +                                    let name = n.[1..n.Length-2]
  +                                    match fields |> List.tryFind (fun (n, _) -> name = n) with
  +                                    | Some f -> f
  +                                    | None -> failwithf "Path argument doesn't correspond to a field: %s" n
  +                                else
  +                                    failwith "Path arguments must be of the shape: {fieldName}")
  +                            |> List.ofArray
  +                        MetaObject (ctor, name, args)
  +                | _ -> MetaBase parseMeth
  +        | ArrayType (t, 1) ->
  +            MetaSequence((let x = Id.New() in Lambda([x], Var x)), t)
  +        | t -> failwithf "Type not supported by RouteMap: %s" t.AssemblyQualifiedName
   
       let routeShapeT = concrete(Reflection.getTypeDefinition typeof<RouteShape>, [])
       let rec convertRouteShape = function
  -        | MetaRoot -> NewUnionCase (routeShapeT, "Root", [])
  -        | MetaPath (name, args) ->
  -            NewUnionCase (routeShapeT, "Path",
  +        | MetaBase parse ->
  +            NewUnionCase(routeShapeT, "Base",
                   [
  +                    (let x = Id.New() in Lambda ([x],
  +                        Call (None, concrete(parsersT, []), concrete(parse, []), [Var x])))
  +                ]
  +            )
  +        | MetaObject (init, name, args) ->
  +            NewUnionCase (routeShapeT, "Object",
  +                [
  +                    init
                       (match name with
                       | Some name -> some stringT (Value (String name))
                       | None -> none stringT)
                       NewArray (args |> List.map (fun (argName, argType) ->
  -                        let meth args res =
  -                            Hashed {
  -                                MethodName = argType.FullName
  -                                Parameters = args
  -                                ReturnType = res
  -                                Generics = 0
  -                            }
                           let argType' = Reflection.getType argType
  -                        let parseMeth = meth [listOf stringT] (optionOf (TupleType [argType'; listOf stringT]))
  -                        match comp.LookupMethodInfo(parsersT, parseMeth) with
  -                        | Metadata.LookupMemberError _ ->
  -                            let shape = getRouteShape argType |> convertRouteShape
  -                            let shapeId = Id.New()
  -                            let init, _ = getDefaultCtor argType'
  -                            Let(shapeId, shape,
  -                                NewArray [
  -                                    Value (String argName)
  -                                    Call (None, routeMapBuilderT, parseShapeM, [Var shapeId; init])
  -                                    Call (None, routeMapBuilderT, makeLinkM, [Var shapeId])
  -                                ]
  -                            )
  -                        | _ ->
  -                            let stringM =
  -                                let m = Hashed {
  -                                    MethodName = "ToString"
  -                                    Parameters = [GenericType 0]
  -                                    ReturnType = stringT
  -                                    Generics = 1
  -                                }
  -                                concrete(m, [argType'])
  +                        let shape = getRouteShape argType' |> convertRouteShape
  +                        let shapeId = Id.New()
  +                        Let(shapeId, shape,
                               NewArray [
                                   Value (String argName)
  -                                (let x = Id.New() in Lambda ([x],
  -                                    Call (None, concrete(parsersT, []), concrete(parseMeth, []), [Var x])))
  -                                (let x = Id.New() in Lambda([x],
  -                                    cons (listOf stringT)
  -                                        <| Call (None, concrete(fsCoreType "Core.Operators", []), stringM, [Var x])
  -                                        <| emptyList (listOf stringT)))
  -                            ]))
  +                                Call (None, routeItemParsersT, parseShapeM, [Var shapeId])
  +                                Call (None, routeItemParsersT, makeLinkM, [Var shapeId])
  +                            ]
  +                        )
  +                    ))
                   ])
  +        | MetaSequence (fromArray, item) ->
  +            let shape = getRouteShape item |> convertRouteShape
  +            let shapeId = Id.New()
  +            Let(shapeId, shape,
  +                NewUnionCase (routeShapeT, "Sequence",
  +                    [
  +                        fromArray
  +                        Call (None, routeItemParsersT, parseShapeM, [Var shapeId])
  +                        Call (None, routeItemParsersT, makeLinkM, [Var shapeId])
  +                    ])
  +            )
   
       override __.TranslateCall(_, _, m, args, _) =
           match m.Generics.[0] with
  
positive.code:             try
                  match m.Entity.Value.MethodName with
                  | "Link" ->
                      match targ with
                      | ConcreteType ct ->
                          let mk = Id.New()
                          let action = Id.New()
                          let t = Reflection.loadType targ
                          let routeShape = getRouteShape t |> convertRouteShape
                          Let (mk, Call (None, routeMapBuilderT, makeLinkM, [routeShape]),
                              Lambda ([action],
                                  Conditional (TypeCheck (Var action, targ),
                                      some (listOf stringT) (Application (Var mk, [Var action])),
                                      none (listOf stringT)
                                  )
                              )
                          )
                      | _ -> failwith "Can only create a link for a concrete type"
                  | "Route" ->
                      let init, t = getDefaultCtor targ
                      let routeShape = getRouteShape t |> convertRouteShape
                      Call (None, routeMapBuilderT, parseRouteM, [routeShape; init])
                  | "Render" ->
                      let go = Id.New()
                      let action = Id.New()
  
negative.code: 
  and [<JavaScript>] private RouteItemParsers =
  
      static member private ParseShape(shape: RouteShape) : ParseFunc =
          fun (path: list<string>) ->
              let parseArgs (init: unit -> obj) (rest: list<string>) (args: RouteObjectArgs) =
                  let v = init()
                  (Some rest, args)
                  ||> Seq.fold (fun rest (name, parse, _) ->
                      match rest with
                      | None -> None
                      | Some rest ->
                          match parse rest with
                          | None -> None
                          | Some (parsed, rest) ->
                              v?(name) <- parsed
                              Some rest
                  )
                  |> Option.map (fun rest -> (v, rest))
              match shape with
              | Base f -> f path
              | Object (init, Some name, args) ->
                  match path with
                  | root :: rest when root = name -> parseArgs init rest args
                  | _ -> None
              | Object (init, None, args) -> parseArgs init path args
              | Sequence (fromArray, parseItem, _) ->
                  RouteItemParsers.``System.Int32`` path
                  |> Option.bind (fun (length, rest) ->
                      let arr = Array.zeroCreate<obj> length
                      let rec set i rest =
                          if i = length then
                              Some (fromArray arr, rest)
                          else
                              match parseItem rest with
                              | None -> None
                              | Some (item, rest) ->
                                  arr.[i] <- item
                                  set (i + 1) rest
                      set 0 rest
                  )
  
      static member private ParseRoute(shape) =
          RouteItemParsers.ParseShape(shape) >> Option.bind (function
              | x, [] -> Some x
              | _ -> None
          )
  
      static member private MakeLink(shape: RouteShape) : LinkFunc =
          fun (value: obj) ->
              match shape with
              | Base _ -> [string value]
              | Object (_, name, args) ->
                  Option.toList name @
                  (args
                  |> Seq.collect (fun (name, _, link) -> link value?(name))
                  |> List.ofSeq)
              | Sequence (_, _, linkItem) ->
                  let s = value :?> seq<obj>
                  ([[string (Seq.length s)]], s)
                  ||> Seq.fold (fun a b -> linkItem b :: a)
                  |> List.rev
                  |> List.concat
  
      static member ``System.String``(x: list<string>) =
          match x with
          | [] -> None
  