Draft: Error handling for mailbox uploads
This branch makes it possible to resend messages and acks without waiting for retransmission timeouts if an exception or crash happens when writing to a high-latency simplex transport (such as a file that will be uploaded to a mailbox).
Each SimplexOutgoingSession can optionally have a unique SyncSessionId associated with it. If the session has an ID, the IDs of any messages sent or acked during the session are stored in the database. If the session completes successfully, the message IDs are removed. If an IO exception occurs, the session is "reset" by resetting the retransmission times of any messages sent in the session and raising the ack flags of any messages acked in the session, so that the messages are eligible to be sent/acked again immediately.
Any incomplete sessions that are found in the DB at startup are reset, so that if the app crashes before a session completes, any messages sent/acked in the session are eligible to be sent/acked again after restarting the app.
SimplexOutgoingSession is refactored to do all its work on a single IO thread, which fixes #1319 (closed).
The equals() methods are removed from subclasses of UniqueId, as these methods broke the contract of equals(). The superclass Bytes already has an equals() method that would consider any subclass instance with the same contents to be equal, but the subclass equals() methods would not consider a superclass instance with the same contents to be equal. This shouldn't have any impact on existing code as we don't make comparisons between different UniqueId types.
Closes #1319 (closed), #2226 (closed)