private void moveOrResizeSelection(boolean up, boolean singleSelection, int count) {
    if (singleSelection) {
      assert mySelectionLength != 0;
      int index;
      if (mySelectionLength > 0) {
        index = up
                ? Math.max(mySelectionIndex + mySelectionLength - 1 - count, 0)
                : Math.min(mySelectionIndex + mySelectionLength - 1 + count, myComponents.size() - 1);
      }
      else {
        index = up
                ? Math.max(mySelectionIndex + mySelectionLength + 1 - count, 0)
                : Math.min(mySelectionIndex + mySelectionLength + 1 + count, myComponents.size() - 1);
      }
      clearSelectionWithout(index);
      singleSelection(index);
    }
    // multi selection
    else if (up) {
      if (mySelectionLength > 0) {
        if (mySelectionIndex + mySelectionLength - 1 > 0) {
          clearAllOrMixSelection();
          for (int i = 0; i < count && mySelectionIndex + mySelectionLength - 1 > 0; i++) {
            mySelectionLength--;
            if (mySelectionLength > 0) {
              myComponents.get(mySelectionIndex + mySelectionLength).setSelection(SelectionType.NONE, true);
            }
            if (mySelectionLength == 0) {
              myComponents.get(mySelectionIndex - 1).setSelection(SelectionType.SELECTION);
              mySelectionLength = -2;
              int newCount = count - i - 1;
              if (newCount > 0) {
                moveOrResizeSelection(true, false, newCount);
              }
              fireSelectionEvent();
              return;
            }
          }
          fireSelectionEvent();
        }
      }
      else if (mySelectionIndex + mySelectionLength + 1 > 0) {
        clearAllOrMixSelection();
        for (int i = 0, index = mySelectionIndex + mySelectionLength + 1; i < count && index > 0; i++, index--) {
          mySelectionLength--;
          myComponents.get(index - 1).setSelection(SelectionType.SELECTION);
        }
        fireSelectionEvent();
      }
    }
    // down
    else if (mySelectionLength > 0) {
      if (mySelectionIndex + mySelectionLength < myComponents.size()) {
        clearAllOrMixSelection();
        for (int i = 0, index = mySelectionIndex + mySelectionLength, size = myComponents.size();
             i < count && index < size;
             i++, index++) {
          myComponents.get(index).setSelection(SelectionType.SELECTION);
          mySelectionLength++;
        }
        fireSelectionEvent();
      }
    }
    else {
      clearAllOrMixSelection();
      for (int i = 0; i < count; i++) {
        mySelectionLength++;
        myComponents.get(mySelectionIndex + mySelectionLength).setSelection(SelectionType.NONE, true);
        if (mySelectionLength == -1) {
          mySelectionLength = 1;
          int newCount = count - i - 1;
          if (newCount > 0) {
            moveOrResizeSelection(false, false, newCount);
          }
          fireSelectionEvent();
          return;
        }
      }
      fireSelectionEvent();
    }
  }
private void moveOrResizeSelection(boolean up, boolean singleSelection, int count)