private void recursivelyProcessComponent(ComputationContext context, int componentRef) {
   BatchReportReader reportReader = context.getReportReader();
   BatchReport.Component component = reportReader.readComponent(componentRef);
   List<BatchReport.Issue> issues = reportReader.readComponentIssues(componentRef);
   issueComputation.processComponentIssues(context, issues, component.getUuid(), componentRef);
   for (Integer childRef : component.getChildRefList()) {
     recursivelyProcessComponent(context, childRef);
   }
 }
 @Override
 public BatchReport.Metadata readMetadata() {
   if (this.metadata == null) {
     this.metadata = delegate.readMetadata();
   }
   return this.metadata;
 }
 @Override
 public CloseableIterator<String> readScannerLogs() {
   File file = delegate.getFileStructure().analysisLog();
   if (!file.exists()) {
     return CloseableIterator.emptyCloseableIterator();
   }
   try {
     InputStreamReader reader =
         new InputStreamReader(FileUtils.openInputStream(file), StandardCharsets.UTF_8);
     return new LineReaderIterator(reader);
   } catch (IOException e) {
     throw new IllegalStateException("Fail to open file " + file, e);
   }
 }
  @Override
  public Optional<CloseableIterator<String>> readFileSource(int fileRef) {
    File file = delegate.readFileSource(fileRef);
    if (file == null) {
      return Optional.absent();
    }

    try {
      return Optional.<CloseableIterator<String>>of(
          new CloseableLineIterator(
              IOUtils.lineIterator(FileUtils.openInputStream(file), StandardCharsets.UTF_8)));
    } catch (IOException e) {
      throw new IllegalStateException("Fail to traverse file: " + file, e);
    }
  }
  @Override
  public CloseableIterator<BatchReport.CoverageDetail> readCoverageDetails(int testFileRef) {
    File file = delegate.readCoverageDetails(testFileRef);
    if (file == null) {
      return CloseableIterator.emptyCloseableIterator();
    }

    try {
      return new ParserCloseableIterator<>(
          BatchReport.CoverageDetail.PARSER, FileUtils.openInputStream(file));
    } catch (IOException e) {
      Throwables.propagate(e);
      // actually never reached
      return CloseableIterator.emptyCloseableIterator();
    }
  }
 @Override
 public CloseableIterator<BatchReport.Duplication> readComponentDuplications(int componentRef) {
   return delegate.readComponentDuplications(componentRef);
 }
 @Override
 public CloseableIterator<BatchReport.Issue> readComponentIssues(int componentRef) {
   return delegate.readComponentIssues(componentRef);
 }
 @Override
 public BatchReport.Component readComponent(int componentRef) {
   return delegate.readComponent(componentRef);
 }
 @Override
 @CheckForNull
 public BatchReport.Changesets readChangesets(int componentRef) {
   return delegate.readChangesets(componentRef);
 }
 @Override
 public CloseableIterator<BatchReport.ActiveRule> readActiveRules() {
   return delegate.readActiveRules();
 }
 @Override
 public CloseableIterator<BatchReport.Coverage> readComponentCoverage(int fileRef) {
   return delegate.readComponentCoverage(fileRef);
 }
 @Override
 public CloseableIterator<BatchReport.SyntaxHighlighting> readComponentSyntaxHighlighting(
     int fileRef) {
   return delegate.readComponentSyntaxHighlighting(fileRef);
 }
 @Override
 public CloseableIterator<BatchReport.Symbol> readComponentSymbols(int componentRef) {
   return delegate.readComponentSymbols(componentRef);
 }