protected void initialize(IPreferenceStore store) {
    // Setup the Mark Occurrences
    fMarkOccurrenceAnnotations =
        store.getBoolean(
            com.aptana.editor.common.preferences.IPreferenceConstants.EDITOR_MARK_OCCURRENCES);
    fStickyOccurrenceAnnotations = store.getBoolean(PreferenceConstants.EDITOR_STICKY_OCCURRENCES);
    fMarkTypeOccurrences = store.getBoolean(PreferenceConstants.EDITOR_MARK_TYPE_OCCURRENCES);
    fMarkMethodOccurrences = store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_OCCURRENCES);
    fMarkFunctionOccurrences =
        store.getBoolean(PreferenceConstants.EDITOR_MARK_FUNCTION_OCCURRENCES);
    fMarkConstantOccurrences =
        store.getBoolean(PreferenceConstants.EDITOR_MARK_CONSTANT_OCCURRENCES);
    fMarkGlobalVariableOccurrences =
        store.getBoolean(PreferenceConstants.EDITOR_MARK_GLOBAL_VARIABLE_OCCURRENCES);
    fMarkLocalVariableOccurrences =
        store.getBoolean(PreferenceConstants.EDITOR_MARK_LOCAL_VARIABLE_OCCURRENCES);
    fMarkImplementors = store.getBoolean(PreferenceConstants.EDITOR_MARK_IMPLEMENTORS);
    fMarkMethodExitPoints = store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_EXIT_POINTS);
    fMarkBreakContinueTargets =
        store.getBoolean(PreferenceConstants.EDITOR_MARK_BREAK_CONTINUE_TARGETS);

    fActivationListener = new ActivationListener();
    PlatformUI.getWorkbench().addWindowListener(fActivationListener);

    if (editor.isMarkingOccurrences()) {
      installOccurrencesFinder(true);
    }

    store.addPropertyChangeListener(this);
  }
  void removeOccurrenceAnnotations() {
    fMarkOccurrenceModificationStamp = IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
    fMarkOccurrenceTargetRegion = null;

    IDocumentProvider documentProvider = editor.getDocumentProvider();
    if (documentProvider == null) return;

    IAnnotationModel annotationModel = documentProvider.getAnnotationModel(editor.getEditorInput());
    if (annotationModel == null || fOccurrenceAnnotations == null) return;

    synchronized (getAnnotationModelLock(annotationModel)) {
      if (annotationModel instanceof IAnnotationModelExtension) {
        ((IAnnotationModelExtension) annotationModel)
            .replaceAnnotations(fOccurrenceAnnotations, null);
      } else {
        for (int i = 0, length = fOccurrenceAnnotations.length; i < length; i++)
          annotationModel.removeAnnotation(fOccurrenceAnnotations[i]);
      }
      fOccurrenceAnnotations = null;
    }
  }
  protected void installOccurrencesFinder(boolean forceUpdate) {
    fMarkOccurrenceAnnotations = true;

    fPostSelectionListenerWithAST =
        new ISelectionListenerWithAST() {
          public void selectionChanged(
              IEditorPart part, ITextSelection selection, Program astRoot) {
            updateOccurrenceAnnotations(selection, astRoot);
          }
        };
    SelectionListenerWithASTManager.getDefault().addListener(editor, fPostSelectionListenerWithAST);
    if (forceUpdate && editor.getSelectionProvider() != null) {
      fForcedMarkOccurrencesSelection = editor.getSelectionProvider().getSelection();
      IModelElement source = editor.getSourceModule();
      if (source != null) {
        try {
          final Program ast =
              SharedASTProvider.getAST(
                  (ISourceModule) source, SharedASTProvider.WAIT_NO, editor.getProgressMonitor());
          updateOccurrenceAnnotations((ITextSelection) fForcedMarkOccurrencesSelection, ast);
        } catch (Exception e) {
          IdeLog.logError(
              PHPEditorPlugin.getDefault(),
              "Error installing the PHP occurrences finder",
              e); //$NON-NLS-1$
        }
      }
    }

    if (fOccurrencesFinderJobCanceler == null) {
      fOccurrencesFinderJobCanceler = new OccurrencesFinderJobCanceler();
      fOccurrencesFinderJobCanceler.install();
    }

    // TODO Do we need some way to hook into reconciling to force an update? Won't typing changed
    // the "selection"
    // anyhow?
  }
  /**
   * 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();
  }