/**
   * Tries and find an Acceleo compiled module (emtl file) corresponding to the given module (mtl
   * file), then loads it as an EMF resource.
   *
   * @param moduleFile The module file of which we seek the compiled version.
   * @param resourceSet The resource set in which to load the module.
   * @return The Acceleo compiled module (emtl file) corresponding to the given module (mtl file).
   *     <code>null</code> if none.
   */
  private static Resource getModule(IFile moduleFile, ResourceSet resourceSet) {
    IFile compiledModule = null;
    if (IAcceleoConstants.MTL_FILE_EXTENSION.equals(moduleFile.getFileExtension())) {
      final IProject project = moduleFile.getProject();
      if (project != null) {
        final String compiledName =
            moduleFile
                .getFullPath()
                .removeFileExtension()
                .addFileExtension(IAcceleoConstants.EMTL_FILE_EXTENSION)
                .lastSegment();
        compiledModule = findChild(project, compiledName);
      }
    }

    Resource module = null;
    if (compiledModule != null) {
      String path = compiledModule.getFullPath().toString();
      for (Resource resource : resourceSet.getResources()) {
        if (resource.getURI().toString().equals(path)) {
          return resource;
        }
      }
      try {
        module =
            ModelUtils.load(URI.createPlatformResourceURI(path, true), resourceSet).eResource();
      } catch (IOException e) {
        // FIXME log
      }
    }
    return module;
  }
  /**
   * {@inheritDoc}
   *
   * @see java.util.concurrent.Callable#call()
   */
  public CompilationResult call() throws Exception {
    checkCancelled();

    String fullExpression = acceleoSource.rebuildFullExpression(context);

    ResourceSet resourceSet = new ResourceSetImpl();
    Resource resource =
        ModelUtils.createResource(
            URI.createURI("http://acceleo.eclipse.org/default.emtl"), resourceSet); // $NON-NLS-1$

    AcceleoSourceBuffer source = new AcceleoSourceBuffer(new StringBuffer(fullExpression));

    List<URI> dependencies = new ArrayList<URI>();
    if (acceleoSource.getModuleImport() != null) {
      dependencies.addAll(computeImportList(acceleoSource.getModuleImport(), resourceSet));
    }

    AcceleoParser parser = new AcceleoParser();
    parser.parse(source, resource, dependencies);

    checkCancelled();

    ASTNode selectedNode = null;
    if (!resource.getContents().isEmpty()) {
      Module module = (Module) resource.getContents().get(0);

      ISelection selection = context.getSelection();
      if (selection instanceof ITextSelection && ((ITextSelection) selection).getLength() > 0) {
        ITextSelection textSelection = (ITextSelection) selection;
        int startOffset = textSelection.getOffset() + acceleoSource.getGap();
        int endOffset = startOffset + textSelection.getLength();

        if (textSelection.getText().startsWith("[")) { // $NON-NLS-1$
          startOffset++;
        }
        if (textSelection.getText().endsWith("/]")) { // $NON-NLS-1$
          endOffset -= 2;
        }

        selectedNode = getChildrenCandidate(module, startOffset, endOffset);

        if (textSelection.getLength() == 0) {
          while (selectedNode != null && !(selectedNode instanceof ModuleElement)) {
            selectedNode = (ASTNode) selectedNode.eContainer();
          }
        }
      }

      if (selectedNode == null && module != null && !module.getOwnedModuleElement().isEmpty()) {
        selectedNode = module.getOwnedModuleElement().get(0);
      }
    }

    checkCancelled();

    IStatus problems = parseProblems(source.getProblems(), source.getWarnings(), source.getInfos());
    return new CompilationResult(selectedNode, problems);
  }
 /**
  * Check the '.emtl' file and report in the '.mtl' file some syntax errors when we use the
  * non-standard library.
  *
  * @param iFile is the '.mtl' file
  * @param oURI is the URI of the '.emtl' file
  */
 private void checkFullOMGCompliance(File iFile, URI oURI) {
   try {
     AcceleoSourceBuffer buffer = new AcceleoSourceBuffer(iFile);
     ResourceSet oResourceSet = new ResourceSetImpl();
     EObject oRoot = ModelUtils.load(oURI, oResourceSet);
     TreeIterator<EObject> oAllContents = oRoot.eAllContents();
     while (oAllContents.hasNext()) {
       EObject oNext = oAllContents.next();
       if (oNext instanceof OperationCallExp) {
         OperationCallExp oOperationCallExp = (OperationCallExp) oNext;
         if (oOperationCallExp.getReferredOperation() != null
             && oOperationCallExp.getReferredOperation().getEAnnotation("MTL non-standard")
                 != null) { //$NON-NLS-1$
           IFile workspaceFile =
               ResourcesPlugin.getWorkspace()
                   .getRoot()
                   .getFileForLocation(new Path(iFile.getAbsolutePath()));
           if (workspaceFile != null
               && workspaceFile.isAccessible()
               && oOperationCallExp.getStartPosition() > -1) {
             int line = buffer.getLineOfOffset(oOperationCallExp.getStartPosition());
             AcceleoMarkerUtils.createMarkerOnFile(
                 AcceleoMarkerUtils.PROBLEM_MARKER_ID,
                 workspaceFile,
                 line,
                 oOperationCallExp.getStartPosition(),
                 oOperationCallExp.getEndPosition(),
                 AcceleoUIMessages.getString(
                     "AcceleoCompileOperation.NotFullyCompliant",
                     oOperationCallExp //$NON-NLS-1$
                         .getReferredOperation()
                         .getName()));
           }
         }
       }
     }
   } catch (IOException e) {
     Status status = new Status(IStatus.WARNING, AcceleoUIActivator.PLUGIN_ID, e.getMessage(), e);
     AcceleoUIActivator.getDefault().getLog().log(status);
   } catch (CoreException e) {
     AcceleoUIActivator.getDefault().getLog().log(e.getStatus());
   }
 }