anchor.diff:              if el.NodeName.ToLower().StartsWith "ws-" then
                   convertInstantiation el
               else
  -                convertAttrs el
  +                Prepare.convertAttrs el
                   convertNodeAndSiblings el.FirstChild
   
           and convertNodeAndSiblings (n: Node) =
               if n !==. null then
                   let next = n.NextSibling
                   if n.NodeType = Dom.NodeType.Text then
  -                    convertTextNode n
  +                    Prepare.convertTextNode n
                   elif n.NodeType = Dom.NodeType.Element then
                       convertElement (n :?> Dom.Element)
                   convertNodeAndSiblings next
   
  -        and convertTemplateFromBody (name: string) =
  -            match JS.Document.Body.QuerySelector("[ws-template=" + name + "]") with
  -            | null ->
  -                match JS.Document.Body.QuerySelector("[ws-children-template=" + name + "]") with
  -                | null -> failNotLoaded name
  -                | n ->
  -                    let name = n.GetAttribute "ws-children-template"
  -                    n.RemoveAttribute "ws-children-template"
  -                    PrepareTemplateStrict "" (Some name) (DomUtility.ChildrenArray n) None None
  -            | n ->
  -                let name = n.GetAttribute "ws-template"
  -                PrepareSingleTemplate baseName (Some name) n None
  -
           and convertInstantiation (el: Dom.Element) =
  -            let currentIsLocal = baseName = ""
               let name = el.NodeName.[3..].ToLower()
  -            let baseName, name =
  +            let instBaseName, instName =
                   match name.IndexOf('.') with
                   | -1 -> baseName, name
                   | n -> name.[..n-1], name.[n+1..]
  -            if baseName <> "" && not (LoadedTemplates.ContainsKey baseName) then
  -                failNotLoaded name
  +            if instBaseName <> "" && not (LoadedTemplates.ContainsKey instBaseName) then
  +                Prepare.failNotLoaded instName
               else
  -            if baseName = "" && prepareLocalTemplate.IsSome then
  -                prepareLocalTemplate.Value name
  -            let d = LoadedTemplates.[baseName]
  -            if not (d.ContainsKey name) then
  -                if currentIsLocal then convertTemplateFromBody name else failNotLoaded name
  -            let t = d.[name]
  +            if instBaseName = "" && prepareLocalTemplate.IsSome then
  +                prepareLocalTemplate.Value instName
  +            let d = LoadedTemplates.[instBaseName]
  +            if not (d.ContainsKey instName) then Prepare.failNotLoaded instName else
  +            let t = d.[instName]
               let instance = t.CloneNode(true) :?> Dom.Element
               let usedHoles = HashSet()
               let mappings = Dictionary()
  
positive.code:                             ))
                      e.SetAttribute(attrName, s)
  
          let fillTextHole (instance: Dom.Element) (fillWith: string) =
              match instance.QuerySelector "[ws-replace]" with
              | null ->
                  Console.Warn("Filling non-existent text hole", name)
                  None
              | n ->
                  n.ParentNode.ReplaceChild(Dom.Text fillWith, n) |> ignore
  
negative.code:                 p.ReplaceChild(n, el) |> ignore
          FakeRoot [| el |]
  
      module private Prepare =
  
          let convertAttrs (el: Dom.Element) =
              let attrs = el.Attributes
              let toRemove = [||]
  