MODE-1819 Changed how WorkspaceCache is used inside user transactions

Added a new specialization of WorkspaceCache called
TransactionWorkspaceCache that is used in place of WorkspaceCache
any time a ReadOnlySessionCache or WritableSessionCache is used
during the scope of a running user transaction.

Normally, each RepositoryCache instance has for each workspace a
single WorkspaceCache instance shared by all sessions. However, in
the case of a session is running within a user transaction, it is
possible for the session (or other sessions that are also participating
in the same user transaction) to persist node changes in the document
store but to not commit the transaction. This means that such
persisted-but-not-committed node representations should be visible to
the sessions running within the transaction but should not be visible
to sessions outside of the transaction. Because the shared
WorkspaceCache lazily loads the requested nodes using the transactional
scope of the requestor, this means that the WorkspaceCache may load
these persisted-but-not-committed node representations and make them
available to other sessions (outside the transaction boundary) and
thereby leaking transactionally-scoped data. Similarly,
a WorkspaceCache that already has the persisted-and-committed node
representations from other sessions will expose those already-cached
forms to sessions running within the transaction, thereby causing
some of the sessions in the same user transaction to not see the
transactionally-scoped (e.g., persisted-but-not-committed) changes.

Therefore, such sessions running within user transactions need a
transactionally-scoped WorkspaceCache instance rather than sharing
the commont WorkspaceCache instance. However, the ModeShape
infrastructure is not set up to handle lots of WorkspaceCache instances
for the same workspace, so we have to be careful about any
transaction-specific caches.

This new design changes the AbstractSessionCache to maintain the original
reference to the real (shared) WorkspaceCache, but to also have another
WorkspaceCache reference that may change (depending upon whether there
is a current user transaction) to a transient TransactionalWorkspaceCache
instance specific to the transaction.

Originally, I tried to have the TransactionalWorkspaceCache do no
caching whatsoever, but this caused problems within the
WritableSessionCache's persistChanges logic, which needs access to
the persisted representation of the node prior to when each changed
node was actually changed. So, the TWC simply uses an in-memory
ConcurrentHashMap. (The alternative was to use another Infinispan
cache such as the one used for the shared workspace caches, but this
would dramatically increase the complexity of the system and would
require an additional cache container configured with different settings
than the normal workspace caches and to use a different naming
convention.)

Several new test cases were added to verify that multiple sessions
within the same user transaction do indeed all see the same
transactionally-scoped data, while other sessions that are outside
of the user transaction do indeed not see any of the transactionally-
scoped changes until commit occurs.