/**
  * Create a new TableItem at index if required.
  *
  * @param element
  * @param index
  * @since 3.1
  */
 private void createItem(Object element, int index) {
   if (virtualManager == null) {
     updateItem(internalCreateNewRowPart(SWT.NONE, index).getItem(), element);
   } else {
     virtualManager.notVisibleAdded(element, index);
   }
 }
  /**
   * Removes the given elements from this table viewer.
   *
   * @param elements the elements to remove
   */
  private void internalRemove(final Object[] elements) {
    Object input = getInput();
    for (int i = 0; i < elements.length; ++i) {
      if (equals(elements[i], input)) {
        boolean oldBusy = isBusy();
        setBusy(false);
        try {
          setInput(null);
        } finally {
          setBusy(oldBusy);
        }
        return;
      }
    }
    // use remove(int[]) rather than repeated TableItem.dispose() calls
    // to allow SWT to optimize multiple removals
    int[] indices = new int[elements.length];
    int count = 0;
    for (int i = 0; i < elements.length; ++i) {
      Widget w = findItem(elements[i]);
      if (w == null && virtualManager != null) {
        int index = virtualManager.find(elements[i]);
        if (index != -1) {
          indices[count++] = index;
        }
      } else if (w instanceof Item) {
        Item item = (Item) w;
        disassociate(item);
        indices[count++] = doIndexOf(item);
      }
    }
    if (count < indices.length) {
      System.arraycopy(indices, 0, indices = new int[count], 0, count);
    }
    if (virtualManager != null) {
      virtualManager.removeIndices(indices);
    }
    doRemove(indices);

    // Workaround for 1GDGN4Q: ITPUI:WIN2000 - TableViewer icons get
    // scrunched
    if (doGetItemCount() == 0) {
      doRemoveAll();
    }
  }
  /**
   * Refresh all with virtual elements.
   *
   * @since 3.1
   */
  private void internalVirtualRefreshAll() {

    Object root = getRoot();
    IContentProvider contentProvider = getContentProvider();

    // Invalidate for lazy
    if (!(contentProvider instanceof ILazyContentProvider)
        && (contentProvider instanceof IStructuredContentProvider)) {
      // Don't cache if the root is null but cache if it is not lazy.
      if (root != null) {
        virtualManager.cachedElements = getSortedChildren(root);
        doSetItemCount(virtualManager.cachedElements.length);
      }
    }
    doClearAll();
  }
 /**
  * Set the item count of the receiver.
  *
  * @param count the new table size.
  * @since 3.1
  */
 public void setItemCount(int count) {
   if (checkBusy()) return;
   int oldCount = doGetItemCount();
   if (count < oldCount) {
     // need to disassociate elements that are being disposed
     for (int i = count; i < oldCount; i++) {
       Item item = doGetItem(i);
       if (item.getData() != null) {
         disassociate(item);
       }
     }
   }
   doSetItemCount(count);
   if (virtualManager != null) {
     virtualManager.adjustCacheSize(count);
   }
   getControl().redraw();
 }
  /**
   * Refresh all of the elements of the table. update the labels if updatLabels is true;
   *
   * @param updateLabels
   * @since 3.1
   */
  private void internalRefreshAll(boolean updateLabels) {
    // the parent

    // in the code below, it is important to do all disassociates
    // before any associates, since a later disassociate can undo an
    // earlier associate
    // e.g. if (a, b) is replaced by (b, a), the disassociate of b to
    // item 1 could undo
    // the associate of b to item 0.

    Object[] children = getSortedChildren(getRoot());
    Item[] items = doGetItems();
    int min = Math.min(children.length, items.length);
    for (int i = 0; i < min; ++i) {

      Item item = items[i];

      // if the element is unchanged, update its label if appropriate
      if (equals(children[i], item.getData())) {
        if (updateLabels) {
          updateItem(item, children[i]);
        } else {
          // associate the new element, even if equal to the old
          // one,
          // to remove stale references (see bug 31314)
          associate(children[i], item);
        }
      } else {
        // updateItem does an associate(...), which can mess up
        // the associations if the order of elements has changed.
        // E.g. (a, b) -> (b, a) first replaces a->0 with b->0, then
        // replaces b->1 with a->1, but this actually removes b->0.
        // So, if the object associated with this item has changed,
        // just disassociate it for now, and update it below.
        // we also need to reset the item (set its text,images etc. to
        // default values) because the label decorators rely on this
        disassociate(item);
        doClear(i);
      }
    }
    // dispose of all items beyond the end of the current elements
    if (min < items.length) {
      for (int i = items.length; --i >= min; ) {

        disassociate(items[i]);
      }
      if (virtualManager != null) {
        virtualManager.removeIndicesFromTo(min, items.length - 1);
      }
      doRemove(min, items.length - 1);
    }
    // Workaround for 1GDGN4Q: ITPUI:WIN2000 - TableViewer icons get
    // scrunched
    if (doGetItemCount() == 0) {
      doRemoveAll();
    }
    // Update items which were disassociated above
    for (int i = 0; i < min; ++i) {

      Item item = items[i];
      if (item.getData() == null) {
        updateItem(item, children[i]);
      }
    }
    // add any remaining elements
    for (int i = min; i < children.length; ++i) {
      createItem(children[i], i);
    }
  }