private BinaryIndex call(BinaryIndex b, BinaryIndex e) { if (b.equals(e.sub())) { return b; } BinaryIndex u = b.add(e.sub(b).div()); BinaryIndex l = u.sub(); Long lv = this.eval(l); Long uv = this.eval(u); if (this.limit_ == lv) { return l; } if (this.limit_ == uv) { return u; } ArrayList<BinaryIndex> tmp = new ArrayList<BinaryIndex>(); if (this.limit_ < lv) { tmp.add(this.call(b, u)); } if (this.limit_ > uv) { tmp.add(this.call(u, e)); } if (tmp.isEmpty()) { return l; } return Collections.max( tmp, new Comparator<BinaryIndex>() { @Override public int compare(BinaryIndex l, BinaryIndex r) { return BinarySearch.this.eval(l).compareTo(BinarySearch.this.eval(r)); } }); }