// returns two int indices packed into one long. left index is for the real file array half, right
  // is for the adopted children name array
  private static long findIndexInBoth(
      @NotNull VirtualFileSystemEntry[] array,
      @NotNull String name,
      @NotNull Comparator comparator) {
    int high = array.length - 1;
    if (high == -1) {
      return pack(-1, -1);
    }
    int low = 0;
    boolean startInAdopted = isAdoptedChild(array[low]);
    boolean endInAdopted = isAdoptedChild(array[high]);
    if (startInAdopted == endInAdopted) {
      int index = findIndexInOneHalf(array, low, high + 1, startInAdopted, name, comparator);
      int otherIndex = startInAdopted ? -1 : -array.length - 1;
      return startInAdopted ? pack(otherIndex, index) : pack(index, otherIndex);
    }
    boolean adopted = false;
    int cmp = -1;
    int mid = -1;
    int foundIndex = -1;
    while (low <= high) {
      mid = low + high >>> 1;
      VirtualFileSystemEntry file = array[mid];
      cmp = comparator.compareFileNameTo(name, file);
      adopted = isAdoptedChild(file);
      if (cmp == 0) {
        foundIndex = mid;
        break;
      }
      if ((adopted || cmp <= 0) && (!adopted || cmp >= 0)) {
        int indexInAdopted = findIndexInOneHalf(array, mid + 1, high + 1, true, name, comparator);
        int indexInReal = findIndexInOneHalf(array, low, mid, false, name, comparator);
        return pack(indexInReal, indexInAdopted);
      }

      if (cmp > 0) {
        low = mid + 1;
      } else {
        high = mid - 1;
      }
    }

    // key not found.
    if (cmp != 0) foundIndex = -low - 1;
    int newStart = adopted ? low : mid + 1;
    int newEnd = adopted ? mid + 1 : high + 1;
    int theOtherHalfIndex =
        newStart < newEnd
            ? findIndexInOneHalf(array, newStart, newEnd, !adopted, name, comparator)
            : -newStart - 1;
    return adopted ? pack(theOtherHalfIndex, foundIndex) : pack(foundIndex, theOtherHalfIndex);
  }
  private static int binSearch(
      @NotNull VirtualFileSystemEntry[] array,
      int start,
      int end,
      @NotNull String name,
      @NotNull Comparator comparator) {
    int low = start;
    int high = end - 1;
    assert low >= 0 && low <= array.length;

    while (low <= high) {
      int mid = low + high >>> 1;
      int cmp = comparator.compareFileNameTo(name, array[mid]);
      if (cmp > 0) {
        low = mid + 1;
      } else if (cmp < 0) {
        high = mid - 1;
      } else {
        return mid; // key found
      }
    }
    return -(low + 1); // key not found.
  }