Allow configuring query caches

Updates `HazelcastQueryResultsRegion` to pass the `HazelcastInstance` through to the `LocalRegionCache`. To retain the existing behavior of not using a `MessageListener`+`ITopic` for invalidation, added a new constructor to `LocalRegionCache`.

In summary:

- Added a new constructor to LocalRegionCache to allow explicit control over whether an ITopic MessageListener should be registered
- Fixed a subtle bug in LocalRegionCache.cleanup() that prevented multiple entries with the same timestamp from being cleaned up
    - Using a TreeSet meant only a single entry at any given timestamp could be considered as a candidate for eviction; subsequent entries were "protected" because they weren't added to the TreeSet
- Updated HazelcastQueryResultsRegion to use the new constructor so that the HazelcastInstance can be passed on (allow query caches to inherit their MapConfigs) without registering a MessageListener
- Added unit tests to verify both LocalRegionCache constructors
- Added unit test to verify HazelcastQueryResultsRegion creates LocalRegionCaches which honor their configurations
I renamed `k` and `i` to make their meanings clearer