#2930 Reference count sessions in WebFilter.

- Rather than storing Boolean.TRUE for the session ID in the cluster map, store a reference count
- Replaced get/put calls with executeOnKey and EntryProcessors to keep network hits low
    - AddSessionEntryProcessor is used to produce the initial reference
    - ReferenceSessionEntryProcessor increments the reference count when a new node looks up a session and creates a local "copy"
    - DestroySessionEntryProcessor decrements the reference count and returns Boolean.TRUE or Boolean.FALSE to indicate whether there are any further references
    - All new EntryProcessors implement IdentifiedDataSerializable for speed
- Renamed InvalidateEntryProcessor->InvalidSessionAttributesEntryProcessor and convert it to IdentifiedDataSerializable
- Updated WebFilter.init to store the WebFilter instance in an attribute on the ServletContext so that SessionListener can look it up
    - This allows WebFilter.destroyOriginalSession to be an instance method which, in turn, allows the session maps to be non-static
    - Having the maps be non-static makes the various WebFilter tests more meaningful because they more accurately simulate two separate servers accessing clustered session state
        - Otherwise, while both servers have their own WebFilter instance, those instances are sharing the same static session maps
- Added a unit test which verifies that session data is removed from the clustered map when the session has timed out on all referencing servers
- Reworded some log messages to make them more clear/useful
- Updated copyright dates from 2013 to 2014
yeah the implementation is wrong, you need to start at one if the current Integer is null, otherwise you have to increment it first :)

```java
public Object process(Map.Entry<String, Integer> entry) {
    Integer startingValue = entry.getValue();
    if (startingValue == null) {
        startingValue = 0;
    }
    entry.setValue(++startingValue);
    return startingValue;
}
```