@Override
  protected boolean executeAnalysis(final IProgressMonitor monitor) throws TmfAnalysisException {
    /* Get the graph */
    TmfGraphBuilderModule graphModule = getGraph();
    if (graphModule == null) {
      Activator.getInstance()
          .logWarning("No graph was found to execute the critical path on"); // $NON-NLS-1$
      return true;
    }
    graphModule.schedule();

    monitor.setTaskName(
        NLS.bind(Messages.CriticalPathModule_waitingForGraph, graphModule.getName()));
    if (!graphModule.waitForCompletion(monitor)) {
      Activator.getInstance()
          .logInfo(
              "Critical path execution: graph building was cancelled.  Results may not be accurate."); //$NON-NLS-1$
      return false;
    }
    TmfGraph graph = graphModule.getGraph();
    if (graph == null) {
      throw new TmfAnalysisException(
          "Critical Path analysis: graph "
              + graphModule.getName()
              + " is null"); //$NON-NLS-1$//$NON-NLS-2$
    }

    /* Get the worker id */
    Object workerObj = getParameter(PARAM_WORKER);
    if (workerObj == null) {
      return false;
    }
    if (!(workerObj instanceof IGraphWorker)) {
      throw new IllegalStateException("Worker parameter must be an IGraphWorker"); // $NON-NLS-1$
    }
    IGraphWorker worker = (IGraphWorker) workerObj;

    TmfVertex head = graph.getHead(worker);
    if (head == null) {
      /* Nothing happens with this worker, return an empty graph */
      fCriticalPath = new TmfGraph();
      return true;
    }

    ICriticalPathAlgorithm cp = getAlgorithm(graph);
    try {
      fCriticalPath = cp.compute(head, null);
      return true;
    } catch (CriticalPathAlgorithmException e) {
      Activator.getInstance().logError(NonNullUtils.nullToEmptyString(e.getMessage()), e);
    }
    return false;
  }
 /**
  * Copy link of type TYPE between nodes FROM and TO in the graph PATH. The return value is the
  * tail node for the new path.
  *
  * @param criticalPath The graph on which to add the link
  * @param graph The original graph on which to calculate critical path
  * @param anchor The anchor vertex from the path graph
  * @param from The origin vertex in the main graph
  * @param to The destination vertex in the main graph
  * @param ts The timestamp of the edge
  * @param type The type of the edge to create
  * @return The destination vertex in the path graph
  */
 public TmfVertex copyLink(
     TmfGraph criticalPath,
     TmfGraph graph,
     TmfVertex anchor,
     TmfVertex from,
     TmfVertex to,
     long ts,
     TmfEdge.EdgeType type) {
   IGraphWorker parentFrom = graph.getParentOf(from);
   IGraphWorker parentTo = graph.getParentOf(to);
   if (parentTo == null) {
     throw new NullPointerException();
   }
   TmfVertex tmp = new TmfVertex(ts);
   criticalPath.add(parentTo, tmp);
   if (parentFrom == parentTo) {
     anchor.linkHorizontal(tmp).setType(type);
   } else {
     anchor.linkVertical(tmp).setType(type);
   }
   return tmp;
 }