/**
   * ------------------------------------------------------ Searches for the next or previous valid
   * part that can receive keyboard focus. Looks at parts, their parts and their parts parts, ...
   *
   * @param parent current parent to start from
   * @param next true if we are to search for next valid part, otherwise we are to search for
   *     previous valid part.
   * @return the valid candidate or null. ------------------------------------------------------
   */
  protected MiPart searchDownTheTree(MiPart parent, boolean next, boolean wentDownALevel) {
    // If parent, whose parts we are going to look at has no parts or is
    // not visible then return nothing.
    if ((parent.getNumberOfParts() == 0) || (!parent.isVisible())) return (null);

    MiiKeyFocusTraversalGroup parentTabGroup = parent.getKeyFocusTraversalGroup();
    if ((parentTabGroup != null) && (parentTabGroup != this)) {
      // First time entering this tabGroup we need to pass in null
      if (wentDownALevel) parent = null;
      return (next ? parentTabGroup.getNext(parent) : parentTabGroup.getPrevious(parent));
    }

    int inc = 1;
    int start = 0;
    if (!next) {
      inc = -1;
      start = parent.getNumberOfParts() - 1;
    }

    for (int i = start; (i >= 0) && (i < parent.getNumberOfParts()); i += inc) {
      MiPart obj = parent.getPart(i);
      // Look at each part...
      if ((obj.isVisible()) && (obj.isSensitive()) && (obj.isAcceptingKeyboardFocus())) {
        return (obj);
      }
      // .. if not valid then look at the parts parts ...
      if ((obj = searchDownTheTree(obj, next, true)) != null) {
        return (obj);
      }
    }
    // ... nothing found in this branch of the tree...
    return (null);
  }
  /**
   * ------------------------------------------------------ Searches for the next or previous valid
   * part that can receive keyboard focus. Looks at siblings, their parts and then parent's siblings
   * and their parts... then looks at
   *
   * @param current current part to start from
   * @param next true if we are to search for next valid part, otherwise we are to search for
   *     previous valid part.
   * @return the valid candidate or null. ------------------------------------------------------
   */
  protected MiPart searchUpTheTree(MiPart current, boolean next) {
    // If current part has no parent or is not visible then nothing is found.
    if ((current.getNumberOfContainers() == 0) || (!current.isVisible())) return (null);

    MiPart part = null;
    MiiKeyFocusTraversalGroup tabGroup = getLocalKeyFocusTraversalGroup(current);
    if (tabGroup != this) {
      part = next ? tabGroup.getNext(current) : tabGroup.getPrevious(current);

      if (part != null) return (part);
    }

    MiPart parent = current.getContainer(0);

    // If parent is at the top level or is not visible then nothing is found.
    if ((parent == target) || (!parent.isVisible())) return (null);

    int index = parent.getIndexOfPart(current);
    // If current part is no longer is parent then nothing is found.
    if (index == -1) return (null);

    int inc = 1;
    if (!next) inc = -1;

    for (int i = index + inc; (i >= 0) && (i < parent.getNumberOfParts()); i += inc) {
      MiPart obj = parent.getPart(i);
      // Look at previous sibling to see if it is a valid candidate...
      if ((obj.isVisible()) && (obj.isSensitive()) && (obj.isAcceptingKeyboardFocus())) {
        if (next) return (obj);
        // Going backwards requires iterating thru the candidate obj's parts
        // before we return the obj itself.
        MiPart tmp = searchDownTheTree(obj, next, false);
        if (tmp != null) return (tmp);
        return (obj);
      }
      // It is not, look at previous sibling's parts to see if one of
      // them are a valid candidate...
      if ((obj = searchDownTheTree(obj, next, false)) != null) {
        return (obj);
      }
    }
    // Going backwards requires iterating thru the candidate obj's parts
    // before we return the obj itself. We have iterated thru the parts
    // now look at the container... (and if going forward, the container
    // has already had key focus on the way here).
    if ((!next)
        && (parent.isVisible())
        && (parent.isSensitive())
        && (parent.isAcceptingKeyboardFocus())) {
      return (parent);
    }
    // Nothing found at the sibling level, go up another level...
    return (searchUpTheTree(parent, next));
  }