anchor.diff:                  if not <| edgesToTerms.ContainsKey e
                   then
                       terminals.Add e.Tag
  -                    nodes.Add <| Terminal (terminals.Length - 1)
  -                    edgesToTerms.Add(e, nodes.Length - 1)
  +                    //nodes.Add <| Terminal (terminals.Length - 1)
  +                    let l = addNode <| Terminal (terminals.Length - 1)
  +                    edgesToTerms.TryAdd(e, l - 1) |> ignore
                   let edge = new Edge(gssVertex, edgesToTerms.[e])
   
                   let ind = tailGssV.FindIndex gssVertex.State gssVertex.Level 
                   if ind = -1 || (tailGssV.Edge ind).Ast <> edgesToTerms.[e]
  -                then addEdge e.Target isNew tailGssV edge true
  +                then addEdge customEnqueue e.Target isNew tailGssV edge true
                  
   
           if not <| currentGraphV.processedGssVertices.Contains(gssVertex)
  
positive.code:                 else ast.other <- Array.append ast.other [|newFamily|]
          | Some _ -> ()
  
      let handlePath (path : Path) (final : Vertex) startV nonTerm pos prod shouldEnqueueVertex =
          let state = parserSource.Gotos.[final.State].[nonTerm]
          let newVertex, isNew = addVertex startV state startV.unprocessedGssVertices
          if shouldEnqueueVertex && isNew 
  
negative.code:     new (head, tail) = new Path(head, tail, if tail = null then 1 else tail.Length + 1)
      new (edge) = new Path (edge, null, 1)
  
  let drawDot (nodes:array<AstNode>) (tokenToNumber : _ -> int) (tokens : BlockResizeArray<_>) (leftSide : int[])
      (initNodes : seq<Vertex>) (numToString : int -> string) (errInd: int) (path : string) =
      use out = new System.IO.StreamWriter (path)
      let was = new Dictionary<_,_>()
      let levels = new Dictionary<_,_>()
      out.WriteLine "digraph GSS {"
      let print s = out.WriteLine ("    " + s)
      let curNum = ref 0
      print "rankdir=RL"
      let getAstString astInd =
          if astInd >= 0 
          then
              match nodes.[astInd] with
              | :? Terminal as i -> tokens.[i.TokenNumber] |> tokenToNumber |> numToString |> sprintf "%s"    
              | :? AST as ast -> 
                  let nonT = 
                      if ast.first.prod < leftSide.Length then ast.first.prod
                      else errInd
                  numToString leftSide.[nonT]
              | _ -> failwith "Unexpected ast"
          else "eps"
  
      let rec dfs (u : Vertex) =
          was.Add (u, !curNum)
          if not <| levels.ContainsKey u.Level then
              levels.[u.Level] <- [!curNum]
          else
              levels.[u.Level] <- !curNum :: levels.[u.Level]
          print <| sprintf "%d [label=\"%d_%d\"]" !curNum u.Level u.State 
          incr curNum
          u.OutEdges |> ResizeArray.iter (handleEdge u)
              
  
      and handleEdge u (e : Edge) =
          let v = e.Dest
          if not <| was.ContainsKey v then
              dfs v
          print <| sprintf "%d -> %d [label=\"%s\"]" was.[u] was.[v] (getAstString e.Ast)
  
      for v in initNodes do
          if not <| was.ContainsKey v then
              dfs v
          
      for level in levels do
          print <| sprintf "{rank=same; %s}" (level.Value |> List.map (fun (u : int) -> string u) |> String.concat " ")
  
      out.WriteLine "}"
      out.Close()
      
  let buildAstAbstract<'TokenType> (parserSource : ParserSource<'TokenType>) (tokens : ParserInputGraph<'TokenType>) =
      let startV, finalV, innerGraph =
          let verticesMap = Array.zeroCreate (Seq.max tokens.Vertices + 1)            
  