/**
  * Applies the checked and grayed states of the given widget and its descendents.
  *
  * @param checked a set of elements (element type: <code>Object</code>)
  * @param grayed a set of elements (element type: <code>Object</code>)
  * @param widget the widget
  */
 private void applyState(CustomHashtable checked, CustomHashtable grayed, Widget widget) {
   Item[] items = getChildren(widget);
   for (int i = 0; i < items.length; i++) {
     Item item = items[i];
     if (item instanceof TreeItem) {
       Object data = item.getData();
       if (data != null) {
         TreeItem ti = (TreeItem) item;
         ti.setChecked(checked.containsKey(data));
         ti.setGrayed(grayed.containsKey(data));
       }
     }
     applyState(checked, grayed, item);
   }
 }
 /**
  * Sets the grayed state of all items to correspond to the given set of grayed elements.
  *
  * @param grayedElements the set (element type: <code>Object</code>) of elements which are grayed
  * @param widget the widget
  */
 private void internalSetGrayed(CustomHashtable grayedElements, Widget widget) {
   Item[] items = getChildren(widget);
   for (int i = 0; i < items.length; i++) {
     TreeItem item = (TreeItem) items[i];
     Object data = item.getData();
     if (data != null) {
       boolean grayed = grayedElements.containsKey(data);
       if (grayed != item.getGrayed()) {
         item.setGrayed(grayed);
       }
     }
     internalSetGrayed(grayedElements, item);
   }
 }
  @Override
  public void remove(Object[] elements) {
    assertElementsNotNull(elements);
    if (checkBusy()) return;
    if (elements.length == 0) {
      return;
    }

    // deselect any items that are being removed, see bug 97786
    boolean deselectedItems = false;
    Object elementToBeRemoved = null;
    CustomHashtable elementsToBeRemoved = null;
    if (elements.length == 1) {
      elementToBeRemoved = elements[0];
    } else {
      elementsToBeRemoved = new CustomHashtable(getComparer());
      for (Object element : elements) {
        elementsToBeRemoved.put(element, element);
      }
    }
    int[] selectionIndices = doGetSelectionIndices();
    for (int index : selectionIndices) {
      Item item = doGetItem(index);
      Object data = item.getData();
      if (data != null) {
        if ((elementsToBeRemoved != null && elementsToBeRemoved.containsKey(data))
            || equals(elementToBeRemoved, data)) {
          table.deselect(index);
          deselectedItems = true;
        }
      }
    }
    super.remove(elements);

    if (deselectedItems) {
      ISelection sel = getSelection();
      updateSelection(sel);
      firePostSelectionChanged(new SelectionChangedEvent(this, sel));
    }
  }