/**
   * @param parent
   * @param initialText
   * @param readOnly
   * @param styles
   */
  public SpellcheckableMessageArea(
      Composite parent, String initialText, boolean readOnly, int styles) {
    super(parent, styles);
    setLayout(new FillLayout());

    AnnotationModel annotationModel = new AnnotationModel();
    sourceViewer =
        new HyperlinkSourceViewer(this, null, null, true, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP);
    getTextWidget().setAlwaysShowScrollBars(false);
    getTextWidget().setFont(UIUtils.getFont(UIPreferences.THEME_CommitMessageEditorFont));

    int endSpacing = 2;
    int textWidth = getCharWidth() * MAX_LINE_WIDTH + endSpacing;
    int textHeight = getLineHeight() * 7;
    Point size = getTextWidget().computeSize(textWidth, textHeight);
    getTextWidget().setSize(size);

    computeBrokenBidiPlatformTextWidth(size.x);

    getTextWidget().setEditable(!readOnly);

    createMarginPainter();

    configureHardWrap();
    final IPropertyChangeListener propertyChangeListener =
        new IPropertyChangeListener() {
          @Override
          public void propertyChange(PropertyChangeEvent event) {
            if (UIPreferences.COMMIT_DIALOG_HARD_WRAP_MESSAGE.equals(event.getProperty())) {
              getDisplay()
                  .asyncExec(
                      new Runnable() {
                        @Override
                        public void run() {
                          configureHardWrap();
                          if (brokenBidiPlatformTextWidth != -1) {
                            layout();
                          }
                        }
                      });
            }
          }
        };
    Activator.getDefault().getPreferenceStore().addPropertyChangeListener(propertyChangeListener);
    final IPropertyChangeListener syntaxColoringChangeListener =
        new IPropertyChangeListener() {
          @Override
          public void propertyChange(PropertyChangeEvent event) {
            if (JFacePreferences.HYPERLINK_COLOR.equals(event.getProperty())) {
              getDisplay()
                  .asyncExec(
                      new Runnable() {
                        @Override
                        public void run() {
                          if (!isDisposed()) {
                            sourceViewer.refresh();
                          }
                        }
                      });
            }
          }
        };
    JFacePreferences.getPreferenceStore().addPropertyChangeListener(syntaxColoringChangeListener);
    final SourceViewerDecorationSupport support = configureAnnotationPreferences();
    if (isEditable(sourceViewer)) {
      quickFixActionHandler = createQuickFixActionHandler(sourceViewer);
    }

    Document document = new Document(initialText);

    configuration =
        new HyperlinkSourceViewer.Configuration(EditorsUI.getPreferenceStore()) {

          @Override
          public int getHyperlinkStateMask(ISourceViewer targetViewer) {
            if (!targetViewer.isEditable()) {
              return SWT.NONE;
            }
            return super.getHyperlinkStateMask(targetViewer);
          }

          @Override
          protected Map getHyperlinkDetectorTargets(ISourceViewer targetViewer) {
            return getHyperlinkTargets();
          }

          @Override
          public IReconciler getReconciler(ISourceViewer viewer) {
            if (!isEditable(viewer)) return null;
            return super.getReconciler(sourceViewer);
          }

          @Override
          public IContentAssistant getContentAssistant(ISourceViewer viewer) {
            if (!viewer.isEditable()) return null;
            IContentAssistant assistant = createContentAssistant(viewer);
            // Add content assist proposal handler if assistant exists
            if (assistant != null)
              contentAssistActionHandler = createContentAssistActionHandler(sourceViewer);
            return assistant;
          }

          @Override
          public IPresentationReconciler getPresentationReconciler(ISourceViewer viewer) {
            PresentationReconciler reconciler = new PresentationReconciler();
            reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(viewer));
            DefaultDamagerRepairer hyperlinkDamagerRepairer =
                new DefaultDamagerRepairer(new HyperlinkTokenScanner(this, viewer));
            reconciler.setDamager(hyperlinkDamagerRepairer, IDocument.DEFAULT_CONTENT_TYPE);
            reconciler.setRepairer(hyperlinkDamagerRepairer, IDocument.DEFAULT_CONTENT_TYPE);
            return reconciler;
          }
        };

    sourceViewer.configure(configuration);
    sourceViewer.setDocument(document, annotationModel);

    configureContextMenu();

    getTextWidget()
        .addDisposeListener(
            new DisposeListener() {
              @Override
              public void widgetDisposed(DisposeEvent disposeEvent) {
                support.uninstall();
                Activator.getDefault()
                    .getPreferenceStore()
                    .removePropertyChangeListener(propertyChangeListener);
                JFacePreferences.getPreferenceStore()
                    .removePropertyChangeListener(syntaxColoringChangeListener);
              }
            });
  }
  /**
   * @param parent
   * @param initialText
   * @param readOnly
   * @param styles
   */
  public SpellcheckableMessageArea(
      Composite parent, String initialText, boolean readOnly, int styles) {
    super(parent, styles);
    setLayout(new FillLayout());

    AnnotationModel annotationModel = new AnnotationModel();
    sourceViewer = new SourceViewer(this, null, null, true, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP);
    getTextWidget().setAlwaysShowScrollBars(false);
    getTextWidget().setFont(UIUtils.getFont(UIPreferences.THEME_CommitMessageEditorFont));

    sys_normalCursor = sourceViewer.getTextWidget().getCursor();
    int endSpacing = 2;
    int textWidth = getCharWidth() * MAX_LINE_WIDTH + endSpacing;
    int textHeight = getLineHeight() * 7;
    Point size = getTextWidget().computeSize(textWidth, textHeight);
    getTextWidget().setSize(size);

    computeBrokenBidiPlatformTextWidth(size.x);

    getTextWidget().setEditable(!readOnly);

    createMarginPainter();

    configureHardWrap();
    final IPropertyChangeListener propertyChangeListener =
        new IPropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent event) {
            if (UIPreferences.COMMIT_DIALOG_HARD_WRAP_MESSAGE.equals(event.getProperty())) {
              getDisplay()
                  .asyncExec(
                      new Runnable() {
                        public void run() {
                          configureHardWrap();
                          if (brokenBidiPlatformTextWidth != -1) {
                            layout();
                          }
                        }
                      });
            }
          }
        };
    Activator.getDefault().getPreferenceStore().addPropertyChangeListener(propertyChangeListener);

    final SourceViewerDecorationSupport support = configureAnnotationPreferences();
    if (isEditable(sourceViewer)) {
      quickFixActionHandler = createQuickFixActionHandler(sourceViewer);
    }

    Document document = new Document(initialText);

    configuration =
        new TextSourceViewerConfiguration(EditorsUI.getPreferenceStore()) {

          public int getHyperlinkStateMask(ISourceViewer targetViewer) {
            return SWT.NONE;
          }

          protected Map getHyperlinkDetectorTargets(ISourceViewer targetViewer) {
            return getHyperlinkTargets();
          }

          @Override
          public IHyperlinkPresenter getHyperlinkPresenter(ISourceViewer targetViewer) {
            return new MultipleHyperlinkPresenter(
                PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_BLUE).getRGB()) {

              @Override
              public void hideHyperlinks() {
                // We want links to always show.
              }
            };
          }

          public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer targetViewer) {
            return getRegisteredHyperlinkDetectors(sourceViewer);
          }

          @Override
          public IReconciler getReconciler(ISourceViewer viewer) {
            if (!isEditable(viewer)) return null;
            return super.getReconciler(sourceViewer);
          }

          public IContentAssistant getContentAssistant(ISourceViewer viewer) {
            if (!viewer.isEditable()) return null;
            IContentAssistant assistant = createContentAssistant(viewer);
            // Add content assist proposal handler if assistant exists
            if (assistant != null)
              contentAssistActionHandler = createContentAssistActionHandler(sourceViewer);
            return assistant;
          }
        };

    sourceViewer.configure(configuration);
    sourceViewer.setDocument(document, annotationModel);

    StyleRange[] styleRanges =
        UIUtils.getHyperlinkDetectorStyleRanges(
            sourceViewer, configuration.getHyperlinkDetectors(sourceViewer));
    sourceViewer.getTextWidget().setStyleRanges(styleRanges);

    configureContextMenu();

    getTextWidget()
        .addDisposeListener(
            new DisposeListener() {
              public void widgetDisposed(DisposeEvent disposeEvent) {
                support.uninstall();
                Activator.getDefault()
                    .getPreferenceStore()
                    .removePropertyChangeListener(propertyChangeListener);
              }
            });
  }