WIP Almost complete refactoring and unit testing of routingtable. Minor refactoring of kbucket.

Very WIP. I will describe tomorrow; really tired now.

### Bugs found:
* Many operations are potentially thread-unsafe.
* The `replacement_cache` isn't synchronized once a `KBucket` is split.
this also reminds me that yes, absolutely, we must make the max range 2**160. As of now, every `key < 2**200` would be in range.

As for the binary search, very necessary.
Maybe put this function somewhere in utils:

```
from bisect import bisect_left
def binary_search(ordered_list, x, lo=0, hi=None):
    hi = hi if hi is not None else len(ordered_list)
    pos = bisect_left(ordered_list, x, lo, hi)
    return (pos if pos != hi and ordered_list[pos] == x else -1)
```

so here I believe you'd use it as follows (if `self.buckets` is indeed an ordered list):
```
index = binary_search(self.buckets, key)
```
I'm not sure though how you'd find out the issue of more than one key for a bucket though, unless you made a copy of the self.buckets, did the search on the copy, removed the found element, and made another search to make sure the next result would be -1 (not found)