anchor.diff:      member this.Dest = destination
       member this.Ast = ast
   
  -type VInfo<'TokenType> (vNum, statesCount) =
  +and VInfo<'TokenType> (vNum, statesCount) =
       member val vNum = vNum with get
  -    //member val curLevelCount = ref 0 with get, set
  -    member val reductions = new ResizeArray<_>(10) with get, set
  -    //member val gssVertices = new ResizeArray<Vertex>() with get
  +    member val reductions = new Queue<_>(10) with get
       member val processedGssVertices = new ResizeArray<Vertex>() with get
       member val unprocessedGssVertices = new ResizeArray<Vertex>() with get
  -    //member val curEdge = ref Unchecked.defaultof<QuickGraph.TaggedEdge<VInfo<'TokenType>,'TokenType>>
  -    //member val curTokNum = ref 0
  -    //member val curToken = ref Unchecked.defaultof<'TokenType>
  -    //member val pushes = new ResizeArray<_>()
   
   let buildAstAbstract<'TokenType> (parserSource : ParserSource<'TokenType>) (tokens : ParserInputGraph<'TokenType>) =
       let statesCount = parserSource.Gotos.Length
  
positive.code: [<AllowNullLiteral>]
  type Vertex (state : int, level : int) =
      let out = new ResizeArray<Edge>(4)
      member this.Level = level
      member this.OutEdges = out
      member this.State = state
      member this.addEdge (edge : Edge) =
          let mutable i = out.Count - 1
          out.Add edge
  
negative.code:             currentGraphV.unprocessedGssVertices.Add v 
          v
  
      let inline addChildren node path prod =
          let family = getFamily node
          let astExists = 
              family
              |> ResizeArray.exists
                  (function (number,children) -> number = prod && Array.forall2 (=) children path)
          if not astExists then
              family.Add (prod, path)
  
      let handlePath (path : _[]) (final : Vertex) currentGraphV startV nonTerm pos prod =
          let state = parserSource.Gotos.[final.State].[nonTerm]
          let newVertex = addVertex startV state None
          let ast = 
              match newVertex.FindIndex final.State final.Level with
              | -1 -> 
                  let edge = new Edge(final, nodes.Count)
                  nodes.Add <| NonTerm (new ResizeArray<_>(1))
                  newVertex.addEdge edge
                  if (pos > 0)
                  then
                      for e in innerGraph.OutEdges currentGraphV do
                          let arr = parserSource.Reduces.[state].[parserSource.TokenToNumber e.Tag]
                          if arr <> null then
                              for (prod, pos) in arr do
                                  currentGraphV.reductions.Enqueue(newVertex, prod, pos, Some edge)
                  edge.Ast
              | x -> (newVertex.Edge x).Ast
          addChildren nodes.[ast] (Microsoft.FSharp.Collections.Array.copy path) prod
  
      let rec walk remainLength (vertex : Vertex) path currentGraphV startV nonTerm pos prod =
          if remainLength = 0 
          then handlePath path vertex currentGraphV startV nonTerm pos prod
          else
              if not (ResizeArray.exists 
                         (fun (_prod, _remainLength, _path, _nonTerm, _pos, _startV) -> 
                                      prod = _prod && remainLength = _remainLength && path = _path && nonTerm = _nonTerm && pos = _pos && startV = _startV)
                         vertex.PassingReductions)
              then vertex.PassingReductions.Add (prod, remainLength, path, nonTerm, pos, startV)
              vertex.OutEdges |> ResizeArray.iter
                  (fun e ->
                      path.[remainLength - 1] <- e.Ast
                      walk (remainLength - 1) e.Dest path currentGraphV startV nonTerm pos prod)
  
      let makeSingleReduction currentGraphV (vertex : Vertex) prod pos (edgeOpt : Edge option) =
          let nonTerm = parserSource.LeftSide.[prod]
  
          if pos = 0 then
              let state = parserSource.Gotos.[vertex.State].[nonTerm]
              let newVertex = addVertex startV state None
              if newVertex.FindIndex vertex.State vertex.Level = -1 then
                  let edge = new Edge(vertex, getEpsilon parserSource.LeftSide.[prod])
                  newVertex.addEdge edge
          else 
              let path = Array.zeroCreate parserSource.Length.[prod]
              for i = path.Length - 1 downto pos do
                  path.[i] <- getEpsilon parserSource.Rules.[parserSource.RulesStart.[prod] + i].[0]
              path.[pos - 1] <- edgeOpt.Value.Ast
              walk (pos - 1) (edgeOpt.Value : Edge).Dest path currentGraphV currentGraphV nonTerm pos prod
  
      let makeReductions (currentGraphV : VInfo<_>) =
          while currentGraphV.reductions.Count > 0 do
              let vertex, prod, pos, edgeOpt = currentGraphV.reductions.Dequeue()
              makeSingleReduction currentGraphV vertex prod pos edgeOpt
  
      let handlePassingReductions (graphV : VInfo<_>) =
          for gssV in graphV.processedGssVertices do
              let passingReductions = gssV.PassingReductions
              for prod, remainLength, path, nonTerm, pos, startV in passingReductions do
                  walk remainLength gssV path graphV startV nonTerm pos prod
  
      let processVertex v onlyReduces = 
          if onlyReduces 
          then
              handlePassingReductions v
          else
              makeReductions v
              for gssVertex in v.unprocessedGssVertices do push v gssVertex gssVertex.State
              v.unprocessedGssVertices.RemoveAll(fun _ -> true) |> ignore
  
      let globalCurV = ref startV
  
      let addReductionsWhenLoop (gssVertices : ResizeArray<Vertex>) (inputEdge : QuickGraph.TaggedEdge<VInfo<_>,_>) = 
          for gssV in inputEdge.Target.processedGssVertices do
              for gssE in gssV.OutEdges do
                  let reductions = new ResizeArray<_>(10)
                  //let edge = new Edge(gssV, nodes.Count)
                  let arr = parserSource.Reduces.[gssV.State].[parserSource.TokenToNumber inputEdge.Tag]
                  if arr <> null then
                      for (prod, pos) in arr do
                          reductions.Add(gssE.Dest, prod, pos, Some gssE, inputEdge.Target)
                      verticesToProcess.Enqueue(inputEdge.Target, true)
                  
                  let reductionSet = new ResizeArray<_>(10)
                  for gssVertex, prod, pos, edge, target in reductions do
                      let reductionExists = 
                          reductionSet
                          |> ResizeArray.exists(function v, p, _pos, e, target -> v = gssVertex && p = prod && _pos = pos && edge = e)
                      if not reductionExists then reductionSet.Add(gssVertex, prod, pos, edge, target)
                  for gssVertex, prod, pos, e, (target : VInfo<_>) in reductionSet do
                      let r = gssVertex, prod, pos, e
                      let reds = target.reductions
                      target.reductions.Enqueue(r)
  
      if tokens.EdgeCount = 0
      then
  