public boolean check(
     SNode root, Set<AbstractConstraintsChecker> checkers, SRepository repository) {
   // returns whether state has been changed after check
   if (root == null) {
     return false;
   }
   invalidate();
   if (myCheckedRoot && SetSequence.fromSet(myInvalidNodes).isEmpty()) {
     return false;
   }
   Queue<SNode> nodesToCheck = QueueSequence.fromQueue(new LinkedList<SNode>());
   QueueSequence.fromQueue(nodesToCheck).addLastElement(root);
   while (QueueSequence.fromQueue(nodesToCheck).isNotEmpty()) {
     SNode node = QueueSequence.fromQueue(nodesToCheck).removeFirstElement();
     if (!(myCheckedRoot) || SetSequence.fromSet(myInvalidNodes).contains(node)) {
       try {
         myCurrentNode = node;
         addDependency(node);
         for (AbstractConstraintsChecker checker : checkers) {
           checker.checkNode(node, this, repository);
         }
       } finally {
         myCurrentNode = null;
       }
     }
     QueueSequence.fromQueue(nodesToCheck)
         .addSequence(ListSequence.fromList(SNodeOperations.getChildren(node)));
   }
   // traversed the whole root, should have been removed all invalid nodes
   SetSequence.fromSet(myInvalidNodes).clear();
   myCheckedRoot = true;
   myUpdateInspector = true;
   return true;
 }