/**
   * Updates the visual of the given TableItem according to its IPathManager.
   *
   * @param item TableItem whose visual needs to be updated
   */
  private void updateTableItem(TableItem item) {

    AVRPathManager path = (AVRPathManager) item.getData();

    // add warn / error icons if path is empty / invalid
    boolean valid = path.isValid();
    boolean optional = path.isOptional();
    boolean empty = (path.getPath().isEmpty());

    if (valid && !empty) {
      // valid path
      item.setImage((Image) null);
    } else if ((valid && empty) || (!valid && optional)) {
      // valid but empty path or invalid and optional path (use for optional paths)
      item.setImage(
          PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_WARN_TSK));
    } else {
      // Path is invalid
      item.setImage(
          PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_ERROR_TSK));
    }

    item.setText(COLUMN_NAME, path.getName());
    item.setText(COLUMN_TYPE, path.getSourceType().toString());
    item.setText(COLUMN_PATH, path.getPath().toOSString());

    // Adjust color/font according to source type
    switch (path.getSourceType()) {
      case System:
        item.setFont(COLUMN_TYPE, fDialogFont);
        item.setFont(COLUMN_PATH, fDialogFont);
        item.setForeground(COLUMN_PATH, fTable.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
        break;
      case Bundled:
        item.setFont(COLUMN_TYPE, fDialogFont);
        item.setFont(COLUMN_PATH, fDialogFont);
        item.setForeground(COLUMN_PATH, fTable.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
        break;
      case Custom:
        item.setFont(COLUMN_TYPE, fBoldFont);
        item.setFont(COLUMN_PATH, fBoldFont);
        item.setForeground(COLUMN_PATH, fTable.getDisplay().getSystemColor(SWT.COLOR_BLACK));
    }

    // Updates the table layout.
    fTable.getColumn(COLUMN_NAME).pack();
    fTable.getColumn(COLUMN_TYPE).pack();
    fTable.getColumn(COLUMN_PATH).pack();
    fTable.layout();
  }
  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jface.preference.FieldEditor#refreshValidState()
   */
  @Override
  protected void refreshValidState() {
    super.refreshValidState();

    // Get all TableItems, extract their IPathManager and check
    // if it is valid and not optional.
    // If any one IPathManager is invalid, the
    // valid boolean is set to false and an error message indicating
    // the culprit is shown.

    TableItem[] allitems = fTable.getItems();
    boolean oldValid = fValid;
    boolean newValid = true;
    String invalidPath = null;

    for (TableItem ti : allitems) {
      AVRPathManager pathitem = (AVRPathManager) ti.getData();
      if (!pathitem.isValid() && !pathitem.isOptional()) {
        newValid = false;
        invalidPath = pathitem.getName();
      }
    }

    // Updates validity and error message.
    fValid = newValid;
    if (fValid == false) {
      showErrorMessage("Path for '" + invalidPath + "' is not valid");
    } else {
      clearErrorMessage();
    }

    // Send some notifications.
    if (newValid != oldValid) {
      fireStateChanged(IS_VALID, oldValid, newValid);
    }
  }