@Override
 public void handleTreeCollapse(TreeEvent event) {
   super.handleTreeCollapse(event);
   for (SynchronizedTreeViewer viewer : synchronizedViewers) {
     TreeItem otherItem = getMatchingItem(event.item.getData(), viewer);
     if (otherItem != null) {
       if (otherItem.getExpanded()) {
         Event rawEvent = new Event();
         rawEvent.doit = true;
         rawEvent.widget = viewer.getTree();
         rawEvent.display = event.display;
         TreeEvent otherEvent = new TreeEvent(rawEvent);
         otherEvent.item = otherItem;
         viewer.internalHandleTreeCollapse(otherEvent);
         viewer.setExpanded(otherItem, false);
       }
       viewer.getTree().redraw();
     }
   }
 }
 protected void synchronizeColumnSize(TreeColumn column) {
   inSynchronization = true;
   if (column != getTree().getColumn(0)) {
     getTree().getColumn(0).setWidth(column.getWidth());
   }
   for (SynchronizedTreeViewer viewer : synchronizedViewers) {
     TreeColumn update = viewer.getTree().getColumn(0);
     if (update != column) {
       update.setWidth(column.getWidth());
     }
   }
   inSynchronization = false;
 }
 public static TreeItem getMatchingItem(Object data, SynchronizedTreeViewer viewer) {
   if (data == null) return null;
   if (data instanceof EmptyElement) {
     data = ((EmptyElement) data).getRepresentedMissingElement();
   }
   TreeItem item = (TreeItem) viewer.findItem(data);
   if (item != null && !item.isDisposed()) {
     if (item.getParentItem() != null && !item.getParentItem().getExpanded()) {
       return null;
     }
     return item;
   }
   // look in the given viewer for any EmptyElement instances
   // that represent the given data
   TreeItem[] items = viewer.getTree().getItems();
   EmptyElement empty = locateEmptyElement(items, data);
   if (empty != null) {
     return (TreeItem) viewer.findItem(empty);
   }
   return null;
 }