private void configureHardWrap() {
    if (shouldHardWrap()) {
      if (hardWrapSegmentListener == null) {
        final StyledText textWidget = getTextWidget();
        hardWrapSegmentListener =
            new BidiSegmentListener() {
              @Override
              public void lineGetSegments(BidiSegmentEvent e) {
                int[] segments = calculateWrapOffsets(e.lineText, MAX_LINE_WIDTH);
                if (segments != null) {
                  char[] segmentsChars = new char[segments.length];
                  Arrays.fill(segmentsChars, '\n');
                  e.segments = segments;
                  e.segmentsChars = segmentsChars;
                }
              }
            };
        textWidget.addBidiSegmentListener(hardWrapSegmentListener);
        textWidget.setText(
            textWidget.getText()); // XXX: workaround for https://bugs.eclipse.org/384886

        if (brokenBidiPlatformTextWidth != -1) {
          Layout restrictedWidthLayout =
              new Layout() {
                @Override
                protected Point computeSize(
                    Composite composite, int wHint, int hHint, boolean flushCache) {
                  Point size = SpellcheckableMessageArea.this.getSize();
                  Rectangle trim = SpellcheckableMessageArea.this.computeTrim(0, 0, 0, 0);
                  size.x -= trim.width;
                  size.y -= trim.height;
                  if (size.x > brokenBidiPlatformTextWidth) size.x = brokenBidiPlatformTextWidth;
                  return size;
                }

                @Override
                protected void layout(Composite composite, boolean flushCache) {
                  Point size = computeSize(composite, SWT.DEFAULT, SWT.DEFAULT, flushCache);
                  textWidget.setBounds(0, 0, size.x, size.y);
                }
              };
          setLayout(restrictedWidthLayout);
        }
      }

    } else if (hardWrapSegmentListener != null) {
      StyledText textWidget = getTextWidget();
      textWidget.removeBidiSegmentListener(hardWrapSegmentListener);
      textWidget.setText(
          textWidget.getText()); // XXX: workaround for https://bugs.eclipse.org/384886
      hardWrapSegmentListener = null;

      if (brokenBidiPlatformTextWidth != -1) setLayout(new FillLayout());
    }
  }
  private void computeBrokenBidiPlatformTextWidth(int textWidth) {
    class BidiSegmentListenerTester implements BidiSegmentListener {
      boolean called;

      public void lineGetSegments(BidiSegmentEvent event) {
        called = true;
      }
    }
    BidiSegmentListenerTester tester = new BidiSegmentListenerTester();
    StyledText textWidget = getTextWidget();
    textWidget.addBidiSegmentListener(tester);
    textWidget.setText(" "); // $NON-NLS-1$
    textWidget.computeSize(SWT.DEFAULT, SWT.DEFAULT);
    textWidget.removeBidiSegmentListener(tester);

    brokenBidiPlatformTextWidth = tester.called ? -1 : textWidth;
  }
  /*
   * @see org.eclipse.jface.text.source.SourceViewer#createControl(org.eclipse.swt.widgets.Composite, int)
   */
  @Override
  protected void createControl(Composite parent, int styles) {

    // Use LEFT_TO_RIGHT unless otherwise specified.
    if ((styles & SWT.RIGHT_TO_LEFT) == 0 && (styles & SWT.LEFT_TO_RIGHT) == 0)
      styles |= SWT.LEFT_TO_RIGHT;

    final int baseLevel =
        (styles & SWT.RIGHT_TO_LEFT) != 0
            ? Bidi.DIRECTION_RIGHT_TO_LEFT
            : Bidi.DIRECTION_LEFT_TO_RIGHT;

    super.createControl(parent, styles);

    fBackspaceManager = new SmartBackspaceManager();
    fBackspaceManager.install(this);

    StyledText text = getTextWidget();
    text.addBidiSegmentListener(
        new BidiSegmentListener() {
          @Override
          public void lineGetSegments(BidiSegmentEvent event) {
            if (redraws()) {
              try {
                event.segments =
                    getBidiLineSegments(
                        getDocument(),
                        baseLevel,
                        widgetOffset2ModelOffset(event.lineOffset),
                        event.lineText);
              } catch (BadLocationException e) {
                // don't touch the segments
              }
            }
          }
        });
  }