Algorithmic optimization for handling frostwire-jlibtorrent alerts.

Designed by @aldenml
Implemented by @aldenml & @gubatron

 - Session now uses a SparseArray of AlertListeners.
 - Cast an alert received from libtorrent land only if there are
   any listeners in the sparse array for that alert type.
 - Got rid of CopyOnWriteLists, as iterating so many times for every
   alert received would create a tremendous amount of Iterator objects
   that would need to be garbage collected.
   However, we still want to have the benefits of having a snapshot of these
   collections to avoid IndexOutOfBound errors, or skipping alert listeners
   when these collections are changed (e.g. adding/removing transfers),
   therefore we're now going to use a secondary collection that keeps
   a corresponding AlertListener[] snapshot, which we can iterate many times,
   contained inside another SparseArray.