/**
  * Returns true iff the given node is a scalar that is not inside a string.
  *
  * @param node {@link ASTNode}
  */
 private boolean isNonStringScalar(ASTNode node) {
   return (node.getType() == ASTNode.SCALAR) && (node.getParent().getType() != ASTNode.QUOTE);
 }
  /**
   * Updates the occurrences annotations based on the current selection.
   *
   * @param selection The text selection
   * @param ast An AST
   */
  protected void updateOccurrenceAnnotations(ITextSelection selection, Program ast) {
    if (fOccurrencesFinderJob != null) fOccurrencesFinderJob.cancel();

    if (!fMarkOccurrenceAnnotations) return;

    if (ast == null || selection == null) return;
    if (!ast.isBindingCompleted()) {
      TypeBindingBuilder.buildBindings(ast);
    }
    IDocument document = editor.getISourceViewer().getDocument();
    if (document == null) return;

    // TODO: Shalom - Replace this to do a real check whether this script was already reconciled
    if (document.getLength() != ast.getEnd()) {
      return;
    }

    boolean hasChanged = false;
    if (document instanceof IDocumentExtension4) {
      int offset = selection.getOffset();
      long currentModificationStamp = ((IDocumentExtension4) document).getModificationStamp();
      IRegion markOccurrenceTargetRegion = fMarkOccurrenceTargetRegion;
      hasChanged = currentModificationStamp != fMarkOccurrenceModificationStamp;
      if (markOccurrenceTargetRegion != null && !hasChanged) {
        if (markOccurrenceTargetRegion.getOffset() <= offset
            && offset
                <= markOccurrenceTargetRegion.getOffset() + markOccurrenceTargetRegion.getLength())
          return;
      }
      fMarkOccurrenceTargetRegion = ScriptWordFinder.findWord(document, offset);
      fMarkOccurrenceModificationStamp = currentModificationStamp;
    }

    OccurrenceLocation[] locations = null;

    ASTNode selectedNode = NodeFinder.perform(ast, selection.getOffset(), selection.getLength());

    // if (locations == null && fMarkExceptions)
    // {
    // TODO: Shalom - Implement
    // }

    if (locations == null && fMarkMethodExitPoints) {
      IOccurrencesFinder finder = OccurrencesFinderFactory.createMethodExitsFinder();
      if (finder.initialize(ast, selectedNode) == null) {
        locations = finder.getOccurrences();
      }
    }

    if (locations == null && fMarkImplementors) {
      IOccurrencesFinder finder = OccurrencesFinderFactory.createIncludeFinder();
      if (finder.initialize(ast, selectedNode) == null) {
        locations = finder.getOccurrences();
      }
    }

    if (locations == null && fMarkBreakContinueTargets) {
      IOccurrencesFinder finder = OccurrencesFinderFactory.createBreakContinueTargetFinder();
      if (finder.initialize(ast, selectedNode) == null) {
        locations = finder.getOccurrences();
      }
    }

    if (locations == null && fMarkImplementors) {
      IOccurrencesFinder finder = OccurrencesFinderFactory.createImplementorsOccurrencesFinder();
      if (finder.initialize(ast, selectedNode) == null) {
        locations = finder.getOccurrences();
      }
    }

    if (selectedNode != null && selectedNode.getType() == ASTNode.VARIABLE) {
      final Expression name = ((Variable) selectedNode).getName();
      if (name instanceof Identifier) {
        selectedNode = name;
      }
    }

    if (locations == null
        && selectedNode != null
        && (selectedNode instanceof Identifier || (isNonStringScalar(selectedNode)))) {
      int type = PhpElementConciliator.concile(selectedNode);
      if (isMarkingOccurrencesFor(type)) {
        IOccurrencesFinder finder = OccurrencesFinderFactory.getOccurrencesFinder(type);
        if (finder != null) {
          if (finder.initialize(ast, selectedNode) == null) {
            locations = finder.getOccurrences();
          }
        }
      }
    }

    if (locations == null) {
      if (!fStickyOccurrenceAnnotations) {
        removeOccurrenceAnnotations();
      } else if (hasChanged) // check consistency of current annotations
      {
        removeOccurrenceAnnotations();
      }
      return;
    }

    fOccurrencesFinderJob = new OccurrencesFinderJob(document, locations, selection);
    fOccurrencesFinderJob.setPriority(Job.DECORATE);
    fOccurrencesFinderJob.schedule();
  }