code: private LineType parseLine(final String line, final LineType... allowedLineTypes) throws ExceptionParseException {
          for (final LineType possibleType : allowedLineTypes) {
              if ((possibleType == LineType.POST_END) || (possibleType == LineType.PRE_START)) {
                  // this is garbage, all is accepted without parsing
                  return possibleType;
              }
              final ExceptionLine parsedLine = possibleType.parse(line);
              if (parsedLine != null) {
                  if (possibleType == LineType.PRE_STACK_TRACE) {
                      // in case the cause is multi-line, update the cause
                      final ExceptionLine currentTop = this.parsedLines.remove(this.parsedLines.size() - 1);
                      if (!((currentTop instanceof CauseLine) && (parsedLine instanceof PlainTextLine))) {
                          throw new IllegalStateException("Garbage in the exception message.");
                      }
                      this.parsedLines.add(new CauseLine((CauseLine) currentTop, (PlainTextLine) parsedLine));
                  } else {
                      this.parsedLines.add(parsedLine);
                  }
                  return possibleType;
              }
          }
          throw new ExceptionParseException(line, "Line not any of the expected types: "
                  + Arrays.toString(allowedLineTypes));
      }
docs: Parse one line in the log, when knowing the types of lines acceptable at
  this point in the log.
  
  @param line
  Line to parse.
  @param allowedLineTypes
  Possible line types, in the order of evaluation. (Possible
  transitions.) If evaluation matches for a type, transition
  will be made and any subsequent types will be ignored.
  @return Identified type of this line.
  @throws ExceptionParseException
  If no allowed types match.