/**
   * Check how RegexErrorParser parses output.
   *
   * @throws Exception...
   */
  public void testRegexErrorParserExternalLocation_bug301338() throws Exception {
    RegexErrorParser regexErrorParser = new RegexErrorParser();
    regexErrorParser.addPattern(
        new RegexErrorPattern(
            "pattern", "", "", "", "$0", IMarkerGenerator.SEVERITY_ERROR_RESOURCE, true));

    errorList.clear();
    ErrorParserManager epManager = new ErrorParserManager(fProject, markerGenerator, new String[0]);

    regexErrorParser.processLine("wrong pattern", epManager);
    regexErrorParser.processLine("pattern wrong", epManager);

    assertEquals(0, errorList.size());
  }
  /**
   * Check that regular error parser extension defined in plugin.xml is accessible.
   *
   * @throws Exception...
   */
  public void testExtension() throws Exception {
    // ErrorParserManager.getErrorParser
    {
      IErrorParserNamed errorParser = ErrorParserManager.getErrorParserCopy(REGEX_ERRORPARSER_ID);
      assertNotNull(errorParser);
      assertEquals(REGEX_ERRORPARSER_NAME, errorParser.getName());

      assertTrue(errorParser instanceof RegexErrorParser);
      RegexErrorParser regexErrorParser = (RegexErrorParser) errorParser;
      assertEquals(REGEX_ERRORPARSER_ID, regexErrorParser.getId());
      assertEquals(REGEX_ERRORPARSER_NAME, regexErrorParser.getName());

      RegexErrorPattern[] patterns = regexErrorParser.getPatterns();
      assertEquals(1, patterns.length);

      RegexErrorPattern pattern = patterns[0];
      assertEquals(IMarker.SEVERITY_ERROR, pattern.getSeverity());
      assertEquals(true, pattern.isEatProcessedLine());
      assertEquals("(.*):(.*):regex (.*)", pattern.getPattern());
      assertEquals("$1", pattern.getFileExpression());
      assertEquals("$2", pattern.getLineExpression());
      assertEquals("$3", pattern.getDescriptionExpression());
      assertEquals("", pattern.getVarNameExpression());
    }

    // ErrorParserManager.getErrorParsers
    {
      IErrorParser errorParser = ErrorParserManager.getErrorParserCopy(REGEX_ERRORPARSER_ID);
      assertTrue(errorParser instanceof RegexErrorParser);

      RegexErrorParser regexErrorParser = (RegexErrorParser) errorParser;
      assertEquals(REGEX_ERRORPARSER_ID, regexErrorParser.getId());
      assertEquals(REGEX_ERRORPARSER_NAME, regexErrorParser.getName());
    }
  }
  /**
   * Make sure the order of patterns is preserved.
   *
   * @throws Exception...
   */
  public void testRegexErrorParserPatternOrder() throws Exception {
    final int ERR = IMarkerGenerator.SEVERITY_ERROR_RESOURCE;
    RegexErrorParser regexErrorParser = new RegexErrorParser();
    RegexErrorPattern removable = new RegexErrorPattern("CCC", null, null, null, null, ERR, true);
    regexErrorParser.addPattern(new RegexErrorPattern("AAA", null, null, null, null, ERR, true));
    regexErrorParser.addPattern(new RegexErrorPattern("BBB", null, null, null, null, ERR, true));
    regexErrorParser.addPattern(removable);
    regexErrorParser.addPattern(new RegexErrorPattern("DDD", null, null, null, null, ERR, true));
    regexErrorParser.addPattern(new RegexErrorPattern("ZZZ", null, null, null, null, ERR, true));

    {
      RegexErrorPattern[] patterns = regexErrorParser.getPatterns();
      assertEquals("AAA", patterns[0].getPattern());
      assertEquals("BBB", patterns[1].getPattern());
      assertEquals("CCC", patterns[2].getPattern());
      assertEquals("DDD", patterns[3].getPattern());
      assertEquals("ZZZ", patterns[4].getPattern());
    }

    regexErrorParser.removePattern(removable);

    {
      RegexErrorPattern[] patterns = regexErrorParser.getPatterns();
      assertEquals("AAA", patterns[0].getPattern());
      assertEquals("BBB", patterns[1].getPattern());
      assertEquals("DDD", patterns[2].getPattern());
      assertEquals("ZZZ", patterns[3].getPattern());
    }
  }
  /**
   * Check if error pattern can be added/deleted.
   *
   * @throws Exception...
   */
  public void testRegexErrorParserAddDeletePattern() throws Exception {
    RegexErrorParser regexErrorParser = new RegexErrorParser();
    regexErrorParser.addPattern(
        new RegexErrorPattern(
            "pattern 1", null, null, null, null, RegexErrorPattern.SEVERITY_SKIP, true));
    regexErrorParser.addPattern(
        new RegexErrorPattern(
            "delete me", null, null, null, null, RegexErrorPattern.SEVERITY_SKIP, true));
    regexErrorParser.addPattern(
        new RegexErrorPattern(
            "pattern 3", null, null, null, null, RegexErrorPattern.SEVERITY_SKIP, true));

    // adding patterns
    RegexErrorPattern[] patternsBefore = regexErrorParser.getPatterns();
    assertEquals(3, patternsBefore.length);
    assertEquals("delete me", patternsBefore[1].getPattern());
    RegexErrorPattern next = patternsBefore[2];

    // delete pattern test
    regexErrorParser.removePattern(patternsBefore[1]);

    RegexErrorPattern[] patternsAfter = regexErrorParser.getPatterns();
    assertEquals(2, patternsAfter.length);
    assertEquals(next, patternsAfter[1]);
  }
  /**
   * Make sure special characters are serialized properly.
   *
   * @throws Exception...
   */
  public void testSerializeRegexErrorParserSpecialCharacters() throws Exception {

    final String TESTING_ID = "org.eclipse.cdt.core.test.regexerrorparser";
    final String TESTING_NAME = "<>\"'\\& Error Parser";
    final String TESTING_REGEX = "Pattern-<>\"'\\&";
    final String ALL_IDS =
        ErrorParserManager.toDelimitedString(ErrorParserManager.getErrorParserAvailableIds());
    {
      // Create error parser with the same id as in eclipse registry
      RegexErrorParser regexErrorParser = new RegexErrorParser(TESTING_ID, TESTING_NAME);
      regexErrorParser.addPattern(
          new RegexErrorPattern(
              TESTING_REGEX,
              "line-<>\"'\\&",
              "file-<>\"'\\&",
              "description-<>\"'\\&",
              null,
              IMarkerGenerator.SEVERITY_WARNING,
              false));

      // Add to available parsers
      ErrorParserExtensionManager.setUserDefinedErrorParsersInternal(
          new IErrorParserNamed[] {regexErrorParser});
      assertNotNull(ErrorParserManager.getErrorParserCopy(TESTING_ID));
      // And serialize in persistent storage
      ErrorParserExtensionManager.serializeUserDefinedErrorParsers();
    }

    {
      // Re-load from persistent storage and check it out
      ErrorParserExtensionManager.loadUserDefinedErrorParsers();
      String all =
          ErrorParserManager.toDelimitedString(ErrorParserManager.getErrorParserAvailableIds());
      assertTrue(all.contains(TESTING_ID));

      IErrorParser errorParser = ErrorParserManager.getErrorParserCopy(TESTING_ID);
      assertNotNull(errorParser);
      assertTrue(errorParser instanceof RegexErrorParser);
      RegexErrorParser regexErrorParser = (RegexErrorParser) errorParser;
      assertEquals(TESTING_ID, regexErrorParser.getId());
      assertEquals(TESTING_NAME, regexErrorParser.getName());

      RegexErrorPattern[] errorPatterns = regexErrorParser.getPatterns();
      assertEquals(1, errorPatterns.length);
      assertEquals(TESTING_REGEX, errorPatterns[0].getPattern());
    }
  }
  /**
   * Check how RegexErrorParser parses output.
   *
   * @throws Exception...
   */
  public void testRegexErrorParserParseOutput() throws Exception {
    RegexErrorParser regexErrorParser = new RegexErrorParser();
    regexErrorParser.addPattern(
        new RegexErrorPattern(
            "(.*)#(.*)#(.*)#(.*)",
            "$1",
            "$2",
            "$3 $4",
            "var=$4",
            IMarkerGenerator.SEVERITY_ERROR_RESOURCE,
            true));
    regexErrorParser.addPattern(
        new RegexErrorPattern(
            "(.*)!(skip me)!(.*)!(.*)",
            null,
            null,
            null,
            null,
            RegexErrorPattern.SEVERITY_SKIP,
            true));
    regexErrorParser.addPattern(
        new RegexErrorPattern(
            "(.*)!(Description)!(.*)!(.*)",
            "$4",
            "$3",
            "$2",
            "$1",
            IMarkerGenerator.SEVERITY_WARNING, /*eat-line*/
            false));
    // broken pattern
    regexErrorParser.addPattern(
        new RegexErrorPattern(
            "(.*)!(.*)", "$6", "$7", "$8", "$9", IMarkerGenerator.SEVERITY_WARNING, true));
    regexErrorParser.addPattern(
        new RegexErrorPattern(
            "(.*)!(.*)!(.*)!(.*)", null, null, null, null, IMarkerGenerator.SEVERITY_INFO, true));

    String fileName = "RegexErrorParser.c";
    ResourceHelper.createFile(fProject, fileName);

    errorList.clear();
    ErrorParserManager epManager = new ErrorParserManager(fProject, markerGenerator, new String[0]);

    ProblemMarkerInfo problemMarkerInfo;

    // Regular pattern
    regexErrorParser.processLine(fileName + "#10#Description#Variable", epManager);
    // This should get ignored
    regexErrorParser.processLine("Variable!skip me!10!" + fileName, epManager);
    // Eat-line=false + qualifying next pattern (nulls), i.e. generates 2 problems
    regexErrorParser.processLine("Variable!Description!10!" + fileName, epManager);

    assertEquals(3, errorList.size());

    // Regular
    problemMarkerInfo = errorList.get(0);
    assertEquals(IMarkerGenerator.SEVERITY_ERROR_RESOURCE, problemMarkerInfo.severity);
    assertEquals("L/" + TEST_PROJECT_NAME + "/" + fileName, problemMarkerInfo.file.toString());
    assertEquals(fileName, problemMarkerInfo.file.getName());
    assertEquals(10, problemMarkerInfo.lineNumber);
    assertEquals("Description Variable", problemMarkerInfo.description);
    assertEquals("var=Variable", problemMarkerInfo.variableName);

    // Eat-line
    problemMarkerInfo = errorList.get(1);
    assertEquals(IMarkerGenerator.SEVERITY_WARNING, problemMarkerInfo.severity);
    assertEquals("L/" + TEST_PROJECT_NAME + "/" + fileName, problemMarkerInfo.file.toString());
    assertEquals(fileName, problemMarkerInfo.file.getName());
    assertEquals(10, problemMarkerInfo.lineNumber);
    assertEquals("Description", problemMarkerInfo.description);
    assertEquals("Variable", problemMarkerInfo.variableName);

    // Nulls
    problemMarkerInfo = errorList.get(2);
    assertEquals(IMarkerGenerator.SEVERITY_INFO, problemMarkerInfo.severity);
    assertEquals("P/" + TEST_PROJECT_NAME, problemMarkerInfo.file.toString());
    assertEquals(0, problemMarkerInfo.lineNumber);
    assertEquals("", problemMarkerInfo.description);
    assertEquals("", problemMarkerInfo.variableName);

    // clone & equals
    RegexErrorParser cloned = (RegexErrorParser) regexErrorParser.clone();
    assertTrue(cloned != regexErrorParser);
    assertEquals(regexErrorParser, cloned);
    assertTrue(cloned.getPatterns() != regexErrorParser.getPatterns());
    assertEquals(cloned.getPatterns().length, regexErrorParser.getPatterns().length);
    for (int i = 0; i < regexErrorParser.getPatterns().length; i++) {
      // Checking deep copy
      assertTrue(cloned.getPatterns()[i] != regexErrorParser.getPatterns()[i]);
      assertEquals(cloned.getPatterns()[i], regexErrorParser.getPatterns()[i]);
    }
  }