anchor.diff:                  false
               |(NontermStart (newAst, newAstPrefixes), Pref findPref) ->
                   let nextAst = getNewAst ast newAst
  -                newAstPrefixes.Any(fun newAstPrefix -> isContainPref nextAst newAstPrefix findAst findPrefix)
  +                match wasAstStarts with
  +                |Some starts ->
  +                    if starts.Contains(newAst)
  +                    then
  +                        false
  +                    else
  +                        starts.Add(newAst)
  +                        newAstPrefixes.Any(fun newAstPrefix -> isContainPref nextAst newAstPrefix wasAstStarts findAst findPrefix wasFindStarts)
  +                |None ->
  +                    let newWasAstStarts = new ResizeArray<_>()
  +                    newWasAstStarts.Add(newAst)
  +                    newAstPrefixes.Any(fun newAstPrefix -> isContainPref nextAst newAstPrefix (Some newWasAstStarts) findAst findPrefix wasFindStarts)
               |(NontermStart (newAst, newAstPrefixes), NontermStart (curFindAst, findAstPrefixes)) ->
                   let nextFindAst = getNewAst findAst curFindAst
                   let nextAst = getNewAst ast newAst
  -                findAstPrefixes.All(fun findAstPrefix -> newAstPrefixes.Any(fun newAstPrefix -> isContainPref nextAst newAstPrefix nextFindAst findAstPrefix))
  +                match (wasAstStarts, wasFindStarts) with
  +                |(Some astStarts, Some findStarts) ->
  +                    if findStarts.Contains(curFindAst)
  +                    then
  +                        true
  +                    else
  +                        if astStarts.Contains(newAst)
  +                        then
  +                            false
  +                        else
  +                            findStarts.Add(curFindAst)
  +                            astStarts.Add(newAst)
  +                            findAstPrefixes.All(fun findAstPrefix -> newAstPrefixes.Any(fun newAstPrefix -> isContainPref nextAst newAstPrefix wasAstStarts nextFindAst findAstPrefix wasFindStarts))
  +                |(Some astStarts, None) ->
  +                    if astStarts.Contains(newAst)
  +                    then
  +                        false
  +                    else
  +                        astStarts.Add(newAst)
  +                        let newWasFindStarts = new ResizeArray<_>()
  +                        newWasFindStarts.Add(curFindAst)
  +                        findAstPrefixes.All(fun findAstPrefix -> newAstPrefixes.Any(fun newAstPrefix -> isContainPref nextAst newAstPrefix wasAstStarts nextFindAst findAstPrefix (Some newWasFindStarts)))
  +                |(None, Some findStarts) ->
  +                    if findStarts.Contains(curFindAst)
  +                    then
  +                        true
  +                    else
  +                        findStarts.Add(curFindAst)
  +                        let newWasAstStarts = new ResizeArray<_>()
  +                        newWasAstStarts.Add(newAst)
  +                        findAstPrefixes.All(fun findAstPrefix -> newAstPrefixes.Any(fun newAstPrefix -> isContainPref nextAst newAstPrefix (Some newWasAstStarts) nextFindAst findAstPrefix wasFindStarts))
  +
  +                |(None, None) ->
  +                    let newWasFindStarts = new ResizeArray<_>()
  +                    newWasFindStarts.Add(curFindAst)
  +                    let newWasAstStarts = new ResizeArray<_>()
  +                    newWasAstStarts.Add(newAst)
  +                    findAstPrefixes.All(fun findAstPrefix -> newAstPrefixes.Any(fun newAstPrefix -> isContainPref nextAst newAstPrefix (Some newWasAstStarts) nextFindAst findAstPrefix (Some newWasFindStarts)))
               |(NontermStart (newAst, newAstPrefixes), NontermEnd (curFindAst, findAstPrefixes)) ->
                   let nextAst = getNewAst ast newAst
                   match findAst with
                   |Some fast ->
                       if fast = curFindAst
                       then
  -                        findAstPrefixes.All(fun findAstPrefix -> newAstPrefixes.Any(fun newAstPrefix -> isContainPref nextAst newAstPrefix None findAstPrefix))
  +                        match wasAstStarts with
  +                        |Some starts ->
  +                            if starts.Contains(newAst)
  +                            then
  +                                false
  +                            else
  +                                starts.Add(newAst)
  +                                findAstPrefixes.All(fun findAstPrefix -> newAstPrefixes.Any(fun newAstPrefix -> isContainPref nextAst newAstPrefix wasAstStarts None findAstPrefix wasFindStarts))
  +                        |None ->
  +                            let newWasAstStarts = new ResizeArray<_>()
  +                            newWasAstStarts.Add(newAst)
  +                            findAstPrefixes.All(fun findAstPrefix -> newAstPrefixes.Any(fun newAstPrefix -> isContainPref nextAst newAstPrefix (Some newWasAstStarts) None findAstPrefix wasFindStarts))
                       else 
                           true
                   |None ->
                       true
               |(NontermStart (newAst, newAstPrefixes), End) ->
  -                false //what if newAst - contain empty path?
  +                false //can newAst contain empty path?
               |(NontermEnd (newAst, newAstPrefixes), Pref findPref) ->
                   match ast with
                   |Some xast ->
                       if xast = newAst
                       then
  -                        newAstPrefixes.Any(fun newAstPrefix -> isContainPref None newAstPrefix findAst findPrefix)
  +                        newAstPrefixes.Any(fun newAstPrefix -> isContainPref None newAstPrefix None findAst findPrefix None)
                       else
                           false
                   |None ->
  
positive.code:                         notPushedPrefs.Add(pref)
  
                  for notPushedPref in notPushedPrefs do
                      if not <| commonNonterms.Any(fun ast -> nonTermsAstToPrefixes.[ast].Any(fun astPrefix -> isContainPref (Some ast) astPrefix None notPushedPref))
                      then
                          if not <| errorEdges.ContainsKey(e)
                              then
  
negative.code:         |Some old -> oldAst
          |None -> Some newAst
  
      let rec isContainPref (ast:AstNode option) (curAstPrefix:LabledPrefix<_>) (wasAstStarts:ResizeArray<AstNode> option) (findAst:AstNode option) (findPrefix:LabledPrefix<_>) (wasFindStarts:ResizeArray<AstNode> option) =    //to do
          if curAstPrefix = findPrefix    //bad compare
          then
              true
          else
  