/**
   * {@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);
  }