TreeItem getItemForDifference(TreeDifference difference) {
   for (int i = difference.getPath().getSegmentCount() - 1; i >= 0; i--) {
     Object segment = difference.getPath().getSegment(i);
     TreeItem item = (TreeItem) findItem(ComparableProvider.getComparableTreeObject(segment));
     // if item is null, check for a matching difference with
     // element type of EmptyElement
     if (item == null) {
       if (difference.getMatchingDifference().getElement() instanceof EmptyElement) {
         // if not found then locate the item for the empty element
         item = (TreeItem) findItem(difference.getMatchingDifference().getElement());
       }
     }
     if (item != null && !item.isDisposed()) {
       TreeItem[] topItems = getTree().getItems();
       for (TreeItem top : topItems) {
         if (top == item) {
           return item;
         }
       }
       // else check for expanded state
       if (item.getParentItem().getExpanded() && !item.getBounds().isEmpty()) {
         return item;
       }
     }
   }
   return null;
 }
 public static boolean differenceIsGraphical(TreeDifference difference) {
   Object diffElement = difference.getElement();
   if (diffElement instanceof EmptyElement) {
     diffElement = ((EmptyElement) diffElement).getParent();
     diffElement = ComparableProvider.getComparableTreeObject(diffElement);
   }
   if (diffElement == null) {
     diffElement = difference.getMatchingDifference().getElement();
   }
   if (diffElement != null) {
     return differenceElementIsGraphical(diffElement);
   }
   return false;
 }
 public static TreeItem getPreviousItem(TreeItem parent, TreeDifference difference) {
   int location = difference.getLocation();
   TreeItem[] items = parent.getItems();
   TreeItem prevItem = null;
   if (items.length == 0) {
     prevItem = parent;
   } else if (items.length <= location) {
     prevItem = items[items.length - 1];
   } else if (location < 0) {
     prevItem = parent;
   } else {
     if (location == 0) {
       prevItem = items[0];
     } else {
       prevItem = items[location - 1];
     }
   }
   return prevItem;
 }
 protected void highlightDifferences(GC gc) {
   // if the differencer is null then we are currently
   // in the middle of a content update, skip this paint
   // request
   if (mergeViewer.getDifferencer() == null) {
     return;
   }
   gc.setAdvanced(true);
   gc.setAntialias(SWT.ON);
   Tree tree = getTree();
   List<TreeDifference> differences = mergeViewer.getDifferencer().getLeftDifferences();
   if (mergeViewer.getLeftViewer() != this && mergeViewer.getAncestorTree() != this) {
     differences = mergeViewer.getDifferencer().getRightDifferences();
   }
   for (TreeDifference difference : differences) {
     if (differenceIsGraphical(difference)) {
       // we do not include graphical differences
       // at this time
       continue;
     }
     gc.setForeground(
         getMergeViewer()
             .getColor(
                 PlatformUI.getWorkbench().getDisplay(),
                 getMergeViewer().getStrokeColor(difference)));
     TreeItem item = getItemForDifference(difference);
     if (item == null || item.isDisposed()) {
       continue;
     }
     Rectangle highlightBounds =
         buildHighlightRectangle(
             item, difference.getIncludeChildren() && item.getExpanded(), gc, false, true);
     Rectangle itemBounds = buildHighlightRectangle(item, false, gc, false, true);
     boolean itemMatchesDifference = difference.getElement().equals(item.getData());
     if (!itemMatchesDifference && !(item.getData() instanceof EmptyElement)) {
       gc.setLineDash(new int[] {3});
       gc.setLineStyle(SWT.LINE_CUSTOM);
     } else {
       gc.setLineStyle(SWT.LINE_SOLID);
     }
     gc.drawRoundRectangle(
         highlightBounds.x,
         highlightBounds.y,
         highlightBounds.width,
         highlightBounds.height,
         5,
         5);
     if (mergeViewer.getLeftViewer() == this) {
       gc.drawLine(
           highlightBounds.x + highlightBounds.width,
           highlightBounds.y + (itemBounds.height / 2),
           tree.getClientArea().x + tree.getClientArea().width,
           highlightBounds.y + (itemBounds.height / 2));
     } else {
       gc.drawLine(
           highlightBounds.x,
           highlightBounds.y + (itemBounds.height / 2),
           tree.getClientArea().x,
           highlightBounds.y + (itemBounds.height / 2));
     }
     gc.setLineStyle(SWT.LINE_SOLID);
   }
 }