anchor.diff:    return new JsEquivalenceVisitor().testNodes(node1, node2);
   }
   
  -class JsEquivalenceVisitor implements js.NodeVisitor<bool> {
  -  Link<js.Node> stack1 = const Link<js.Node>();
  -  Link<js.Node> stack2 = const Link<js.Node>();
  +class JsEquivalenceVisitor implements js.NodeVisitor1<bool, js.Node> {
     Map<String, String> labelsMap = <String, String>{};
  -
  -  void push(js.Node node1, js.Node node2) {
  -    stack1 = stack1.prepend(node1);
  -    stack2 = stack2.prepend(node2);
  -  }
  -
  -  js.Node peek() => stack2.head;
  -
  -  void pop() {
  -    stack1 = stack1.tail;
  -    stack2 = stack2.tail;
  -  }
   
     bool failAt(js.Node node1, js.Node node2) {
       print('Node mismatch:');
  
positive.code:   bool testNodes(js.Node node1, js.Node node2) {
      if (identical(node1, node2)) return true;
      if (node1 == null || node2 == null) return failAt(node1, node2);
      push(node1, node2);
      bool result = node1.accept(this);
      pop();
      return result;
    }
  
    bool testNodeLists(List<js.Node> list1, List<js.Node> list2) {
  
negative.code:   }
  
    @override
    bool visitIf(js.If node, js.Node arg) {
      if (arg is! js.If) return failAt(node, arg);
      js.If other = arg;
      return testNodes(node.condition, other.condition) &&
          testNodes(node.then, other.then) &&
          testNodes(node.otherwise, other.otherwise);
    }
  
    @override
    bool visitEmptyStatement(js.EmptyStatement node, js.Node arg) {
      if (arg is! js.EmptyStatement) return failAt(node, arg);
      return true;
    }
  
    @override
    bool visitExpressionStatement(js.ExpressionStatement node, js.Node arg) {
      if (arg is! js.ExpressionStatement) return failAt(node, arg);
      js.ExpressionStatement other = arg;
      return testNodes(node.expression, other.expression);
    }
  
    @override
    bool visitBlock(js.Block node, js.Node arg) {
      if (arg is! js.Block) return failAt(node, arg);
      js.Block other = arg;
      return testNodeLists(node.statements, other.statements);
    }
  }
  