/*
   * @see ITextOperationTargetExtension#enableOperation(int, boolean)
   * @since 2.0
   */
  public void enableOperation(int operation, boolean enable) {

    switch (operation) {
      case CONTENTASSIST_PROPOSALS:
      case CONTENTASSIST_CONTEXT_INFORMATION:
        {
          if (fContentAssistant == null) return;

          if (enable) {
            if (!fContentAssistantInstalled) {
              fContentAssistant.install(this);
              fContentAssistantInstalled = true;
            }
          } else if (fContentAssistantInstalled) {
            fContentAssistant.uninstall();
            fContentAssistantInstalled = false;
          }
          break;
        }
      case QUICK_ASSIST:
        {
          if (fQuickAssistAssistant == null) return;

          if (enable) {
            if (!fQuickAssistAssistantInstalled) {
              fQuickAssistAssistant.install(this);
              fQuickAssistAssistantInstalled = true;
            }
          } else if (fQuickAssistAssistantInstalled) {
            fQuickAssistAssistant.uninstall();
            fQuickAssistAssistantInstalled = false;
          }
        }
    }
  }
  /*
   * @see org.eclipse.jface.text.source.ISourceViewerExtension2#unconfigure()
   * @since 3.0
   */
  public void unconfigure() {
    clearRememberedSelection();

    if (fPresentationReconciler != null) {
      fPresentationReconciler.uninstall();
      fPresentationReconciler = null;
    }

    if (fReconciler != null) {
      fReconciler.uninstall();
      fReconciler = null;
    }

    if (fContentAssistant != null) {
      fContentAssistant.uninstall();
      fContentAssistantInstalled = false;
      fContentAssistant = null;
      if (fContentAssistantFacade != null) fContentAssistantFacade = null;
    }

    if (fQuickAssistAssistant != null) {
      fQuickAssistAssistant.uninstall();
      fQuickAssistAssistantInstalled = false;
      fQuickAssistAssistant = null;
    }

    fContentFormatter = null;

    if (fInformationPresenter != null) {
      fInformationPresenter.uninstall();
      fInformationPresenter = null;
    }

    fAutoIndentStrategies = null;
    fDoubleClickStrategies = null;
    fTextHovers = null;
    fIndentChars = null;
    fDefaultPrefixChars = null;

    if (fVerticalRulerHoveringController != null) {
      fVerticalRulerHoveringController.dispose();
      fVerticalRulerHoveringController = null;
    }

    if (fOverviewRulerHoveringController != null) {
      fOverviewRulerHoveringController.dispose();
      fOverviewRulerHoveringController = null;
    }

    if (fUndoManager != null) {
      fUndoManager.disconnect();
      fUndoManager = null;
    }

    setHyperlinkDetectors(null, SWT.NONE);
  }
 /**
  * Checks whether there's a quick assist assistant and if so, whether the assistant has a possible
  * fix for the given annotation.
  *
  * @param annotation the annotation
  * @return <code>true</code> if there is quick fix
  * @since 3.2
  */
 protected boolean hasQuickFix(Annotation annotation) {
   if (annotation instanceof IQuickFixableAnnotation) {
     IQuickFixableAnnotation quickFixableAnnotation = (IQuickFixableAnnotation) annotation;
     if (!quickFixableAnnotation.isQuickFixableStateSet())
       quickFixableAnnotation.setQuickFixable(
           fQuickAssistAssistant != null && fQuickAssistAssistant.canFix(annotation));
     return quickFixableAnnotation.isQuickFixable();
   }
   return false;
 }
  /*
   * @see ITextOperationTarget#doOperation(int)
   */
  public void doOperation(int operation) {

    if (getTextWidget() == null || (!redraws() && operation != FORMAT)) return;

    switch (operation) {
      case CONTENTASSIST_PROPOSALS:
        fContentAssistant.showPossibleCompletions();
        return;
      case CONTENTASSIST_CONTEXT_INFORMATION:
        fContentAssistant.showContextInformation();
        return;
      case QUICK_ASSIST:
        // FIXME: must find a way to post to the status line
        /* String msg= */ fQuickAssistAssistant.showPossibleQuickAssists();
        // setStatusLineErrorMessage(msg);
        return;
      case INFORMATION:
        fInformationPresenter.showInformation();
        return;
      case FORMAT:
        {
          final Point selection = rememberSelection();
          final IRewriteTarget target = getRewriteTarget();
          final IDocument document = getDocument();
          IFormattingContext context = null;
          DocumentRewriteSession rewriteSession = null;

          if (document instanceof IDocumentExtension4) {
            IDocumentExtension4 extension = (IDocumentExtension4) document;
            DocumentRewriteSessionType type =
                (selection.y == 0 && document.getLength() > 1000) || selection.y > 1000
                    ? DocumentRewriteSessionType.SEQUENTIAL
                    : DocumentRewriteSessionType.UNRESTRICTED_SMALL;
            rewriteSession = extension.startRewriteSession(type);
          } else {
            setRedraw(false);
            target.beginCompoundChange();
          }

          try {

            final String rememberedContents = document.get();

            try {

              if (fContentFormatter instanceof IContentFormatterExtension) {
                final IContentFormatterExtension extension =
                    (IContentFormatterExtension) fContentFormatter;
                context = createFormattingContext();
                if (selection.y == 0) {
                  context.setProperty(FormattingContextProperties.CONTEXT_DOCUMENT, Boolean.TRUE);
                } else {
                  context.setProperty(FormattingContextProperties.CONTEXT_DOCUMENT, Boolean.FALSE);
                  context.setProperty(
                      FormattingContextProperties.CONTEXT_REGION,
                      new Region(selection.x, selection.y));
                }
                extension.format(document, context);
              } else {
                IRegion r;
                if (selection.y == 0) {
                  IRegion coverage = getModelCoverage();
                  r = coverage == null ? new Region(0, 0) : coverage;
                } else {
                  r = new Region(selection.x, selection.y);
                }
                fContentFormatter.format(document, r);
              }

              updateSlaveDocuments(document);

            } catch (RuntimeException x) {
              // fire wall for https://bugs.eclipse.org/bugs/show_bug.cgi?id=47472
              // if something went wrong we undo the changes we just did
              // TODO to be removed after 3.0 M8
              document.set(rememberedContents);
              throw x;
            }

          } finally {

            if (document instanceof IDocumentExtension4) {
              IDocumentExtension4 extension = (IDocumentExtension4) document;
              extension.stopRewriteSession(rewriteSession);
            } else {
              target.endCompoundChange();
              setRedraw(true);
            }

            restoreSelection();
            if (context != null) context.dispose();
          }
          return;
        }
      default:
        super.doOperation(operation);
    }
  }
  /*
   * @see ISourceViewer#configure(SourceViewerConfiguration)
   */
  public void configure(SourceViewerConfiguration configuration) {

    if (getTextWidget() == null) return;

    setDocumentPartitioning(configuration.getConfiguredDocumentPartitioning(this));

    // install content type independent plug-ins
    fPresentationReconciler = configuration.getPresentationReconciler(this);
    if (fPresentationReconciler != null) fPresentationReconciler.install(this);

    fReconciler = configuration.getReconciler(this);
    if (fReconciler != null) fReconciler.install(this);

    fContentAssistant = configuration.getContentAssistant(this);
    if (fContentAssistant != null) {
      fContentAssistant.install(this);
      if (fContentAssistant instanceof IContentAssistantExtension4)
        fContentAssistantFacade = new ContentAssistantFacade(fContentAssistant);
      fContentAssistantInstalled = true;
    }

    fQuickAssistAssistant = configuration.getQuickAssistAssistant(this);
    if (fQuickAssistAssistant != null) {
      fQuickAssistAssistant.install(this);
      fQuickAssistAssistantInstalled = true;
    }

    fContentFormatter = configuration.getContentFormatter(this);

    fInformationPresenter = configuration.getInformationPresenter(this);
    if (fInformationPresenter != null) fInformationPresenter.install(this);

    setUndoManager(configuration.getUndoManager(this));

    getTextWidget().setTabs(configuration.getTabWidth(this));

    setAnnotationHover(configuration.getAnnotationHover(this));
    setOverviewRulerAnnotationHover(configuration.getOverviewRulerAnnotationHover(this));

    setHoverControlCreator(configuration.getInformationControlCreator(this));

    setHyperlinkPresenter(configuration.getHyperlinkPresenter(this));
    IHyperlinkDetector[] hyperlinkDetectors = configuration.getHyperlinkDetectors(this);
    int eventStateMask = configuration.getHyperlinkStateMask(this);
    setHyperlinkDetectors(hyperlinkDetectors, eventStateMask);

    // install content type specific plug-ins
    String[] types = configuration.getConfiguredContentTypes(this);
    for (int i = 0; i < types.length; i++) {

      String t = types[i];

      setAutoEditStrategies(configuration.getAutoEditStrategies(this, t), t);
      setTextDoubleClickStrategy(configuration.getDoubleClickStrategy(this, t), t);

      int[] stateMasks = configuration.getConfiguredTextHoverStateMasks(this, t);
      if (stateMasks != null) {
        for (int j = 0; j < stateMasks.length; j++) {
          int stateMask = stateMasks[j];
          setTextHover(configuration.getTextHover(this, t, stateMask), t, stateMask);
        }
      } else {
        setTextHover(
            configuration.getTextHover(this, t), t, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
      }

      String[] prefixes = configuration.getIndentPrefixes(this, t);
      if (prefixes != null && prefixes.length > 0) setIndentPrefixes(prefixes, t);

      prefixes = configuration.getDefaultPrefixes(this, t);
      if (prefixes != null && prefixes.length > 0) setDefaultPrefixes(prefixes, t);
    }

    activatePlugins();
  }