private Node<U, T> buildSubtree(List<T> intervalList, int low, int high) {
    U point = intervalList.get((low + high) >>> 1).getLow();
    Node<U, T> result = new Node<U, T>(point);

    int lowPointer = low;
    int highPointer = high;
    for (int j = low; j < highPointer; j++) {
      T next = intervalList.get(j);
      if (next.getHigh().compareTo(point) < 0) {
        Collections.swap(intervalList, lowPointer++, j);
      } else if (next.getLow().compareTo(point) > 0) {
        highPointer = j;
      }
    }
    if (low < lowPointer) {
      result.setLeft(buildSubtree(intervalList, low, lowPointer));
    }
    if (highPointer < high) {
      result.setRight(buildSubtree(intervalList, highPointer, high));
    }

    return result;
  }