Major bug fixes in redistribution for the most part

DataExtractor.java
* New static class that returns useful debugging information. It's not used yet.

RedistributionCore.java
* Added a clear method that excludes surplus

RoutingTable.java
* Turned HashMap into a ConcurrentHashMap to avoid thread locks.
* Momentarily commented out the discrepancy printer to save on computing power and speed.

D2TreeCore.java
* Surplus nodes are not accounted for during redistributions anymore. We only redistribute the part of the bucket that hasn't changed from the beginning of the redistribution (using the surplus counter; we assume that buckets hold bucketSize - surplus nodes).
Minor changes-fixes

D2TreeCore.java
* Extend uses routing table data to determine how tall the tree is (size of largest routing table; left vs right) instead of propagating the data from above.
* Slight code cleanup.
* States of the network are now serialized to a binary file.
* Value of surplus is now ignored during transfer as well.

RoutingTable.java
* Made it serializable. Could be handy to be able to save the contents of a RoutingTable object to a binary file.

RedistributionCore.java
* Made it serializable. Could be handy to be able to save the contents of a RedistributionCore object to a binary file.
Extra bucket debugging tools, overhaul of transfer process (can move multiple nodes at once)

D2TreeCore.java
* Split a few methods for readability.
* Transfers can now be performed massively. No longer necessary to move nodes one by one.

DataExtractor.java
* New functions to fetch bucket data.
* * getOrderedBucketNodes traverses a bucket, starting from its first one, all the way to the last, following each peer's RoutingTable links (either to the left or to the right).
* * getBucketNodes(HashMap<Long, RoutingTable> peers): For each node in the network, it checks if it's a bucket node. If so, it puts it in a hashtable with its representative as a key. Returns the resulting Hashtable(leafId -> bucketNodesOfLeaf).
* * getBucketNodes(long bucket): Returns all the nodes that have bucket as their representative.

TransferRequest.java
* Added a variable (passIndex) to better control how many nodes have been transferred during the procedure.

TransferResponse.java
* As a result of no longer having to transfer nodes one by one, TransferType has been replaced by the more relevant "addedNodes" which counts how many nodes have been added during the procedure. If negative, it means that nodes have been removed

RoutingTable.java
* Moved some routing-table related methods here (previously members of D2TreeCore)

PrintMessage.java
* Moved some printing methods here (from D2TreeCore.java)
* Trees are now also printed in a better, more human-friendly format and better for the eyes.