The SortedCopyOnWriteArray didn't wrap the iterator() in a
unmodifiable iterator. In addition, ConcurrentListenerMultimap
incorrectly used the iterator to remove objects from this Array.
Added a "remove(T value)" method that is thread-safe.
API changes:
* The PacketListener now uses a "ListeningWhitelist" class
to report which packet ids it wishes to listen in on for
either the client or the server. This makes it possible to
use your plugin class as the listener more easily.
* Added a priority system similar to Bukkit events.
Performance changes:
* Create and maintain a separate list of listeners for each packet
ID. This uses slightly more memory, but is far more efficient.
Especially in light of the priority system.
In addition, the listener lists are (hopefully) concurrent. They're
optimized for read-access, however. Adding or removing a listener
is a O(n) operation.
While libraries are sometimes licensed under LGPL, or even less
restrictive licenses, in this particular case it doesn't really
make sense to encourage direct copying. The problem is that
competing libraries would conflict with each other. It's better
to feed improvements back into a single project.
Though, it's of course possible to fork this project. You can change
the internal classes - for instance, improving or changing the hook
points - without worriying about the public API.