anchor.diff:          isSynthetic: true, lexeme: '');
   
       token = token.next;
  -    expect((token as fasta.ErrorToken).errorCode,
  -        same(codeUnexpectedDollarInString));
  -
  -    token = token.next;
       expectToken(token, TokenType.STRING, 6, 0, isSynthetic: true, lexeme: '"');
  -
  -    token = token.next;
  -    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  -    expect((token as fasta.UnterminatedString).start, '"');
     }
   
     void test_string_multi_unterminated() {
       Token token = scan("'''string");
  +    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  +    expect((token as fasta.UnterminatedString).start, "'''");
  +
  +    token = token.next;
       expectToken(token, TokenType.STRING, 0, 9,
           lexeme: "'''string'''", isSynthetic: true);
  -
  -    token = token.next;
  -    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  -    expect((token as fasta.UnterminatedString).start, "'''");
     }
   
     void test_string_raw_multi_unterminated() {
       Token token = scan("r'''string");
  +    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  +    expect((token as fasta.UnterminatedString).start, "r'''");
  +
  +    token = token.next;
       expectToken(token, TokenType.STRING, 0, 10,
           lexeme: "r'''string'''", isSynthetic: true);
  -
  -    token = token.next;
  -    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  -    expect((token as fasta.UnterminatedString).start, "r'''");
     }
   
     void test_string_raw_simple_unterminated_eof() {
       Token token = scan("r'string");
  +    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  +    expect((token as fasta.UnterminatedString).start, "r'");
  +
  +    token = token.next;
       expectToken(token, TokenType.STRING, 0, 8,
           lexeme: "r'string'", isSynthetic: true);
  -
  -    token = token.next;
  -    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  -    expect((token as fasta.UnterminatedString).start, "r'");
     }
   
     void test_string_raw_simple_unterminated_eol() {
       Token token = scan("r'string\n");
  +    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  +    expect((token as fasta.UnterminatedString).start, "r'");
  +
  +    token = token.next;
       expectToken(token, TokenType.STRING, 0, 8,
           lexeme: "r'string'", isSynthetic: true);
  -
  -    token = token.next;
  -    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  -    expect((token as fasta.UnterminatedString).start, "r'");
     }
   
     void test_string_simple_unterminated_eof() {
       Token token = scan("'string");
  +    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  +    expect((token as fasta.UnterminatedString).start, "'");
  +
  +    token = token.next;
       expectToken(token, TokenType.STRING, 0, 7,
           lexeme: "'string'", isSynthetic: true);
  -
  -    token = token.next;
  -    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  -    expect((token as fasta.UnterminatedString).start, "'");
     }
   
     void test_string_simple_unterminated_eol() {
       Token token = scan("'string\n");
  +    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  +    expect((token as fasta.UnterminatedString).start, "'");
  +
  +    token = token.next;
       expectToken(token, TokenType.STRING, 0, 7,
           lexeme: "'string'", isSynthetic: true);
  -
  -    token = token.next;
  -    expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
  -    expect((token as fasta.UnterminatedString).start, "'");
     }
   
     void test_match_angle_brackets() {
  
positive.code:   @override
    Token scanWithListener(String source, ErrorListener listener,
        {bool lazyAssignmentOperators: false}) {
      var scanner = new fasta.StringScanner(source, includeComments: true);
      var firstToken = scanner.tokenize();
      Token token = new Token.eof(-1)..setNext(firstToken);
  
      // Translate error tokens
      if (scanner.hasErrors) {
        Token next = firstToken;
        while (!next.isEof) {
          if (next.type.kind == BAD_INPUT_TOKEN) {
            translateErrorToken(next,
                (ScannerErrorCode errorCode, int offset, List<Object> arguments) {
              listener.errors.add(new TestError(offset, errorCode, arguments));
            });
            token.setNext(next.next);
          } else {
            token = next;
          }
          next = token.next;
        }
      }
      return firstToken;
    }
  
    void test_comments() {
  
negative.code:     expect(interpolationStart.endToken, same(token));
  
      token = token.next;
      expectToken(token, TokenType.STRING, 10, 0, isSynthetic: true, lexeme: '"');
    }
  
    void test_string_simple_unterminated_interpolation_block2() {
      Token token = scan(r'"foo ${bar(baz[');
      expect((token as fasta.ErrorToken).errorCode, same(codeUnmatchedToken));
      var openSquareBracketErrorToken = token as fasta.UnmatchedToken;
  
      token = token.next;
      expect((token as fasta.ErrorToken).errorCode, same(codeUnmatchedToken));
      var openParenErrorToken = token as fasta.UnmatchedToken;
  
      token = token.next;
      expect((token as fasta.ErrorToken).errorCode, same(codeUnmatchedToken));
      var interpolationStartErrorToken = token as fasta.UnmatchedToken;
  
      token = token.next;
      expect((token as fasta.ErrorToken).errorCode, same(codeUnterminatedString));
      expect((token as fasta.UnterminatedString).start, '"');
  
      token = token.next;
      expectToken(token, TokenType.STRING, 0, 5, lexeme: '"foo ');
  
      token = token.next;
      expectToken(token, TokenType.STRING_INTERPOLATION_EXPRESSION, 5, 2);
      BeginToken interpolationStart = token;
      expect(interpolationStartErrorToken.begin, same(interpolationStart));
  
      token = token.next;
      expectToken(token, TokenType.IDENTIFIER, 7, 3, lexeme: 'bar');
  