class JavaFileAnalyzer2 extends JavaParserBaseListener implements FileAnalyzer {

  @Override
  public Map<ConstructId, Construct> getConstructs() throws FileAnalysisException {
    if (this.constructs == null) {
      try {
        this.constructs = new TreeMap<ConstructId, Construct>();
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (final InputStream is2 = new BufferedInputStream(new FileInputStream(this.file))) {
          int cc = -1;
          while ((cc = is2.read()) >= 0) baos.write(cc);
        }
        baos.flush();
        this.input = new ANTLRInputStream(new ByteArrayInputStream(baos.toByteArray()));
        JavaLexer lexer = new JavaLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        JavaParser parser = new JavaParser(tokens);
        CompilationUnitContext ctx = parser.compilationUnit();
        ParseTreeWalker walker = new ParseTreeWalker();
        walker.walk(this, ctx);
      } catch (FileNotFoundException e) {
        throw new FileAnalysisException(e.getMessage(), e);
      } catch (RecognitionException e) {
        throw new FileAnalysisException(
            "ANTLR exception while analysing class file ["
                + this.file.getName()
                + "]: "
                + e.getMessage(),
            e);
      } catch (IOException e) {
        throw new FileAnalysisException(
            "I/O exception while analysing class file ["
                + this.file.getName()
                + "]: "
                + e.getMessage(),
            e);
      } catch (Exception e) {
        throw new FileAnalysisException(
            "Exception of type ["
                + e.getClass().getSimpleName()
                + "] while analyzing file ["
                + this.file.toPath().toAbsolutePath()
                + "]: "
                + e.getMessage(),
            e);
      }
    }
    return this.constructs;
  }

}