public Client next_client (Client from, boolean reverse) {
    int index = clients.indexOf (from);
    int n = clients.size ();

    // + n for no negative value
    // % n for cycle
    index = (reverse ? index-1+n : index+1+n) % n;

    Client next = (Client) clients.elementAt (index);

    /* Detect looping.
     *
     * Case !focus_key_pressed: focus is always at the top of
     * clients, i.e., the end of the vector. next == focus means we
     * are searching in a loop. We return null to signal it. Callers should
     * quit recursive searching, and return null to set_focus, which does
     * nothing (as search fails).
     *
     * Case focus_key_pressed: focus_base is the last active window. 
     * Note orders of windows in clients stays constants during
     * focus_key_pressed, and thus focus cannot be used to detect
     * looping. next == focus_base means we are searching in a loop. 
     * We return null to signal it. Callers should quit recursive
     * searching, and return null to set_focus, which, however, sets focus
     * to focus_base, to allow circular tabbing.
     *
     * Note that returning null (instead of focus_base) is critical in
     * next_* () methods as, say, next_client_normal () will be called by,
     * say, next_client_first_char (), returning null in next_client_normal
     * () prevents looping in next_client_first_char ().
     */
    if (focus_key_pressed && next == focus_base) return null;
    if (!focus_key_pressed && next == focus) return null;

    if (next.early_unmapped || next.early_destroyed) 
      return next_client (next, reverse);
    else
      return next;
  }