public void forceCustomAnnotationHover() throws NoSuchFieldException, IllegalAccessException {
    Class<SourceViewer> sourceViewerClazz = SourceViewer.class;
    sourceViewer.setAnnotationHover(new CommentAnnotationHover(null));

    // hack for Eclipse 3.5
    try {
      Field hoverControlCreator = TextViewer.class.getDeclaredField("fHoverControlCreator");
      hoverControlCreator.setAccessible(true);
      hoverControlCreator.set(sourceViewer, new CommentInformationControlCreator());
    } catch (Throwable t) {
      // ignore as it may not exist in other versions
    }

    // hack for Eclipse 3.5
    try {
      Method ensureMethod =
          sourceViewerClazz.getDeclaredMethod("ensureAnnotationHoverManagerInstalled");
      ensureMethod.setAccessible(true);
      ensureMethod.invoke(sourceViewer);
    } catch (Throwable t) {
      // ignore as it may not exist in other versions
    }

    Field hoverManager = SourceViewer.class.getDeclaredField("fVerticalRulerHoveringController");
    hoverManager.setAccessible(true);
    AnnotationBarHoverManager manager = (AnnotationBarHoverManager) hoverManager.get(sourceViewer);
    if (manager != null) {
      Field annotationHover = AnnotationBarHoverManager.class.getDeclaredField("fAnnotationHover");
      annotationHover.setAccessible(true);
      IAnnotationHover hover = (IAnnotationHover) annotationHover.get(manager);
      annotationHover.set(manager, new CommentAnnotationHover(hover));
    }
    sourceViewer.showAnnotations(true);
    sourceViewer.showAnnotationsOverview(true);
  }
  public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
    if (oldInput != null) {
      annotationModel.disconnect(oldInput);
    }
    if (newInput != null && sourceViewer != null) {
      IAnnotationModel originalAnnotationModel = sourceViewer.getAnnotationModel();
      if (originalAnnotationModel instanceof IAnnotationModelExtension) {
        IAnnotationModelExtension annotationModelExtension =
            (IAnnotationModelExtension) originalAnnotationModel;
        annotationModelExtension.addAnnotationModel(
            ReviewsUiPlugin.PLUGIN_ID, originalAnnotationModel);
      } else {
        try {
          Class<SourceViewer> sourceViewerClazz = SourceViewer.class;
          Field declaredField2 = sourceViewerClazz.getDeclaredField("fVisualAnnotationModel");
          declaredField2.setAccessible(true);
          Method declaredMethod =
              sourceViewerClazz.getDeclaredMethod(
                  "createVisualAnnotationModel", IAnnotationModel.class);
          declaredMethod.setAccessible(true);
          originalAnnotationModel =
              (IAnnotationModel) declaredMethod.invoke(sourceViewer, annotationModel);
          declaredField2.set(sourceViewer, originalAnnotationModel);
          originalAnnotationModel.connect(newInput);
          sourceViewer.showAnnotations(true);

          createVerticalRuler(newInput, sourceViewerClazz);
          createOverviewRuler(newInput, sourceViewerClazz);
          createHighlighting(sourceViewerClazz);
        } catch (Throwable t) {
          StatusHandler.log(
              new Status(
                  IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID, "Error attaching annotation model", t));
        }
      }
    }
  }
  /*
   * overview ruler problem: displayed in both viewers. the diff editor ruler is actually custom drawn (see
   * TextMergeViewer.fBirdsEyeCanvas) the ruler that gets created in this method is longer than the editor, meaning its
   * not an overview (not next to the scrollbar)
   */
  @SuppressWarnings("unused")
  private void createOverviewRuler(IDocument newInput, Class<SourceViewer> sourceViewerClazz)
      throws SecurityException, NoSuchMethodException, NoSuchFieldException,
          IllegalArgumentException, IllegalAccessException, InvocationTargetException {

    sourceViewer.setOverviewRulerAnnotationHover(new CommentAnnotationHover(null));

    OverviewRuler ruler =
        new OverviewRuler(
            new DefaultMarkerAnnotationAccess(),
            15,
            EditorsPlugin.getDefault().getSharedTextColors());
    Field compositeField = sourceViewerClazz.getDeclaredField("fComposite");
    compositeField.setAccessible(true);

    ruler.createControl((Composite) compositeField.get(sourceViewer), sourceViewer);
    ruler.setModel(annotationModel);
    // ruler.setModel(compareAnnotationModel.leftAnnotationModel);
    // XXX should go through SourceViewerDecorationSupport instead
    //		ruler.addAnnotationType("org.eclipse.mylyn.reviews.ui.comment.Annotation");
    //		ruler.setAnnotationTypeLayer("org.eclipse.mylyn.reviews.ui.comment.Annotation", 1);
    //		ruler.update();

    IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess();
    final SourceViewerDecorationSupport support =
        new SourceViewerDecorationSupport(
            sourceViewer, ruler, annotationAccess, EditorsUI.getSharedTextColors());
    Iterator<?> e = new MarkerAnnotationPreferences().getAnnotationPreferences().iterator();
    while (e.hasNext()) {
      support.setAnnotationPreference((AnnotationPreference) e.next());
    }
    support.install(EditorsUI.getPreferenceStore());
    sourceViewer
        .getControl()
        .addDisposeListener(
            new DisposeListener() {
              public void widgetDisposed(DisposeEvent e) {
                support.dispose();
              }
            });

    Field overViewRulerField = sourceViewerClazz.getDeclaredField("fOverviewRuler");
    overViewRulerField.setAccessible(true);

    if (overViewRulerField.get(sourceViewer) == null) {
      overViewRulerField.set(sourceViewer, ruler);
    }

    Method declareMethod =
        sourceViewerClazz.getDeclaredMethod("ensureOverviewHoverManagerInstalled");
    declareMethod.setAccessible(true);
    declareMethod.invoke(sourceViewer);
    // overviewRuler is null

    Field hoverManager = sourceViewerClazz.getDeclaredField("fOverviewRulerHoveringController");
    hoverManager.setAccessible(true);
    AnnotationBarHoverManager manager = (AnnotationBarHoverManager) hoverManager.get(sourceViewer);
    if (manager != null) {
      Field annotationHover = AnnotationBarHoverManager.class.getDeclaredField("fAnnotationHover");
      annotationHover.setAccessible(true);
      IAnnotationHover hover = (IAnnotationHover) annotationHover.get(manager);
      annotationHover.set(manager, new CommentAnnotationHover(null));
    }
    sourceViewer.showAnnotations(true);
    sourceViewer.showAnnotationsOverview(true);

    declareMethod =
        sourceViewerClazz.getDeclaredMethod("showAnnotationsOverview", new Class[] {Boolean.TYPE});
    declareMethod.setAccessible(true);
  }