/**
   * Compiles the given list of Acceleo parser messages into a single MultiStatus.
   *
   * @param errors List of the errors that arose during the compilation.
   * @param warnings List of the warnings that arose during the compilation.
   * @param infos List of the infos that arose during the compilation.
   * @return A single MultiStatus referenging all issues.
   */
  private IStatus parseProblems(
      AcceleoParserProblems errors, AcceleoParserWarnings warnings, AcceleoParserInfos infos) {
    List<IStatus> problems = new ArrayList<IStatus>();

    for (AcceleoParserProblem error : errors.getList()) {
      problems.add(new Status(IStatus.ERROR, AcceleoUIActivator.PLUGIN_ID, error.getMessage()));
    }
    for (AcceleoParserWarning warning : warnings.getList()) {
      problems.add(new Status(IStatus.WARNING, AcceleoUIActivator.PLUGIN_ID, warning.getMessage()));
    }
    for (AcceleoParserInfo info : infos.getList()) {
      problems.add(new Status(IStatus.INFO, AcceleoUIActivator.PLUGIN_ID, info.getMessage()));
    }

    if (problems.isEmpty()) {
      return null;
    }

    MultiStatus status =
        new MultiStatus(
            AcceleoUIActivator.PLUGIN_ID,
            1,
            AcceleoUIMessages.getString("acceleo.interpreter.compilation.issue"),
            null); //$NON-NLS-1$
    for (IStatus child : problems) {
      status.add(child);
    }
    return status;
  }
  /**
   * Compiles the templates. Creates an AST model from a list of Acceleo files, using a CST step.
   * The dependencies are loaded before link resolution.
   *
   * @param monitor is the monitor
   * @throws CoreException contains a status object describing the cause of the exception
   */
  private void doCompileResources(IProgressMonitor monitor) throws CoreException {
    AcceleoProject acceleoProject = new AcceleoProject(project);
    List<URI> dependenciesURIs = acceleoProject.getAccessibleOutputFiles();
    List<AcceleoFile> iFiles = new ArrayList<AcceleoFile>();
    List<URI> oURIs = new ArrayList<URI>();
    for (int i = 0; i < files.length; i++) {
      checkCanceled(monitor);
      if (acceleoProject.getOutputFilePath(files[i]) != null) {
        IPath outputPath = acceleoProject.getOutputFilePath(files[i]);
        if (outputPath != null) {
          String javaPackageName = acceleoProject.getPackageName(files[i]);
          AcceleoFile acceleoFile =
              new AcceleoFile(
                  files[i].getLocation().toFile(),
                  AcceleoFile.javaPackageToFullModuleName(
                      javaPackageName,
                      new Path(files[i].getName()).removeFileExtension().lastSegment()));
          iFiles.add(acceleoFile);
          URI platformURI = URI.createPlatformResourceURI(outputPath.toString(), false);
          oURIs.add(platformURI);
        }
      }
    }

    AcceleoParser parser = null;
    AcceleoBuilderSettings settings = new AcceleoBuilderSettings(project);
    String resourceKind = settings.getResourceKind();
    if (AcceleoBuilderSettings.BUILD_XMI_RESOURCE.equals(resourceKind)) {
      parser = new AcceleoParser(false, settings.isTrimmedPositions());
    } else {
      parser = new AcceleoParser(true, settings.isTrimmedPositions());
    }
    parser.parse(
        iFiles, oURIs, dependenciesURIs, null, new BasicMonitor.EclipseSubProgress(monitor, 1));
    for (URI uri : oURIs) {
      try {
        AcceleoUIResourceSet.removeResource(uri);
      } catch (IOException e) {
        AcceleoUIActivator.log(e, true);
      }
    }

    for (Iterator<AcceleoFile> iterator = iFiles.iterator(); iterator.hasNext(); ) {
      AcceleoFile iFile = iterator.next();

      AcceleoParserProblems problems = parser.getProblems(iFile);
      AcceleoParserWarnings warnings = parser.getWarnings(iFile);
      AcceleoParserInfos infos = parser.getInfos(iFile);

      IFile workspaceFile =
          ResourcesPlugin.getWorkspace()
              .getRoot()
              .getFileForLocation(new Path(iFile.getMtlFile().getAbsolutePath()));

      if (workspaceFile != null && workspaceFile.isAccessible()) {
        if (problems != null) {
          List<AcceleoParserProblem> list = problems.getList();
          for (Iterator<AcceleoParserProblem> itProblems = list.iterator();
              itProblems.hasNext(); ) {
            AcceleoParserProblem problem = itProblems.next();
            AcceleoMarkerUtils.createMarkerOnFile(
                AcceleoMarkerUtils.PROBLEM_MARKER_ID,
                workspaceFile,
                problem.getLine(),
                problem.getPosBegin(),
                problem.getPosEnd(),
                problem.getMessage());
          }
        }
        if (warnings != null) {
          List<AcceleoParserWarning> list = warnings.getList();
          for (Iterator<AcceleoParserWarning> itWarnings = list.iterator();
              itWarnings.hasNext(); ) {
            AcceleoParserWarning warning = itWarnings.next();
            AcceleoMarkerUtils.createMarkerOnFile(
                AcceleoMarkerUtils.WARNING_MARKER_ID,
                workspaceFile,
                warning.getLine(),
                warning.getPosBegin(),
                warning.getPosEnd(),
                warning.getMessage());
          }
        }
        if (infos != null) {
          List<AcceleoParserInfo> list = infos.getList();
          for (Iterator<AcceleoParserInfo> itInfos = list.iterator(); itInfos.hasNext(); ) {
            AcceleoParserInfo info = itInfos.next();
            AcceleoMarkerUtils.createMarkerOnFile(
                AcceleoMarkerUtils.INFO_MARKER_ID,
                workspaceFile,
                info.getLine(),
                info.getPosBegin(),
                info.getPosEnd(),
                info.getMessage());
          }
        }
      }
    }

    if (iFiles.size() > 0) {
      AcceleoFile acceleoFile = iFiles.get(0);
      IFile workspaceFile =
          ResourcesPlugin.getWorkspace()
              .getRoot()
              .getFileForLocation(new Path(acceleoFile.getMtlFile().getAbsolutePath()));

      // FIXME Performance problem? We will only check for the first file to compile.
      AcceleoSourceBuffer buffer = new AcceleoSourceBuffer(acceleoFile);
      buffer.createCST();
      Module module = buffer.getCST();
      this.checkDependenciesWithDynamicMetamodels(module, workspaceFile);
    }
    checkCanceled(monitor);
    List<IFile> filesWithMainTag = new ArrayList<IFile>();
    for (Iterator<AcceleoFile> iterator = iFiles.iterator(); iterator.hasNext(); ) {
      AcceleoFile iFile = iterator.next();
      IFile workspaceFile =
          ResourcesPlugin.getWorkspace()
              .getRoot()
              .getFileForLocation(new Path(iFile.getMtlFile().getAbsolutePath()));
      if (workspaceFile != null && workspaceFile.isAccessible() && hasMainTag(workspaceFile)) {
        filesWithMainTag.add(workspaceFile);
      }
    }
    CreateRunnableAcceleoOperation createRunnableAcceleoOperation =
        new CreateRunnableAcceleoOperation(acceleoProject, filesWithMainTag);
    createRunnableAcceleoOperation.run(monitor);

    settings = new AcceleoBuilderSettings(project);
    if (AcceleoBuilderSettings.BUILD_STRICT_MTL_COMPLIANCE == settings.getCompliance()) {
      Iterator<AcceleoFile> itFiles = iFiles.iterator();
      for (Iterator<URI> itURIs = oURIs.iterator();
          !monitor.isCanceled() && itURIs.hasNext() && itFiles.hasNext(); ) {
        AcceleoFile iFile = itFiles.next();
        URI oURI = itURIs.next();
        checkFullOMGCompliance(iFile.getMtlFile(), oURI);
      }
    }
  }