public void handle(
      int problemId,
      String[] problemArguments,
      int elaborationId,
      String[] messageArguments,
      int severity,
      int problemStartPosition,
      int problemEndPosition,
      ReferenceContext referenceContext,
      CompilationResult unitResult) {

    if (severity == ProblemSeverities.Ignore) return;

    // if no reference context, we need to abort from the current compilation process
    if (referenceContext == null) {
      if ((severity & ProblemSeverities.Error) != 0) { // non reportable error is fatal
        CategorizedProblem problem =
            this.createProblem(
                null,
                problemId,
                problemArguments,
                elaborationId,
                messageArguments,
                severity,
                0,
                0,
                0,
                0);
        throw new AbortCompilation(null, problem);
      } else {
        return; // ignore non reportable warning
      }
    }

    int[] lineEnds;
    int lineNumber =
        problemStartPosition >= 0
            ? Util.getLineNumber(
                problemStartPosition,
                lineEnds = unitResult.getLineSeparatorPositions(),
                0,
                lineEnds.length - 1)
            : 0;
    int columnNumber =
        problemStartPosition >= 0
            ? Util.searchColumnNumber(
                unitResult.getLineSeparatorPositions(), lineNumber, problemStartPosition)
            : 0;
    CategorizedProblem problem =
        this.createProblem(
            unitResult.getFileName(),
            problemId,
            problemArguments,
            elaborationId,
            messageArguments,
            severity,
            problemStartPosition,
            problemEndPosition,
            lineNumber,
            columnNumber);

    if (problem == null) return; // problem couldn't be created, ignore

    switch (severity & ProblemSeverities.Error) {
      case ProblemSeverities.Error:
        record(problem, unitResult, referenceContext);
        if ((severity & ProblemSeverities.Fatal) != 0) {
          referenceContext.tagAsHavingErrors();
          // should abort ?
          int abortLevel;
          if ((abortLevel =
                  this.policy.stopOnFirstError()
                      ? ProblemSeverities.AbortCompilation
                      : severity & ProblemSeverities.Abort)
              != 0) {
            referenceContext.abort(abortLevel, problem);
          }
        }
        break;
      case ProblemSeverities.Warning:
        record(problem, unitResult, referenceContext);
        break;
    }
  }