binarySearch

re-written to be cleaner
O(log n)

original approach uses sequential search when target is found, however
its worst case is O(n) since the search for upper and lower bound is not
binary search.

New approach is truly O(log n)